EmulateInstructionARM.cpp revision 68fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7
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" 19c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton#include "lldb/Symbol/UnwindPlan.h" 208482dedc1d0fb4669d1ec63ec259d1cb8eaeb20fGreg Clayton 21f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Plugins/Process/Utility/ARMDefines.h" 22f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Plugins/Process/Utility/ARMUtils.h" 23f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Utility/ARM_DWARF_Registers.h" 24f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton 259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 26930704795c783e5bf1768a43da6f957108b40873Johnny Chen // and CountTrailingZeros_32 function 2764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2864c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonusing namespace lldb; 2964c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonusing namespace lldb_private; 3064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 31e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// Convenient macro definitions. 32b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 33b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 34e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 35f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 36f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 380e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 390e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// ITSession implementation 400e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 410e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 420e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen 43930704795c783e5bf1768a43da6f957108b40873Johnny Chen// A8.6.50 44930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 4504d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonstatic uint32_t 4604d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonCountITSize (uint32_t ITMask) { 47930704795c783e5bf1768a43da6f957108b40873Johnny Chen // First count the trailing zeros of the IT mask. 4804d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton uint32_t TZ = llvm::CountTrailingZeros_32(ITMask); 49930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (TZ > 3) 50930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 51930704795c783e5bf1768a43da6f957108b40873Johnny Chen printf("Encoding error: IT Mask '0000'\n"); 52930704795c783e5bf1768a43da6f957108b40873Johnny Chen return 0; 53930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 54930704795c783e5bf1768a43da6f957108b40873Johnny Chen return (4 - TZ); 55930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 56930704795c783e5bf1768a43da6f957108b40873Johnny Chen 57930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Init ITState. Note that at least one bit is always 1 in mask. 5804d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonbool ITSession::InitIT(uint32_t bits7_0) 59930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 60930704795c783e5bf1768a43da6f957108b40873Johnny Chen ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 61930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (ITCounter == 0) 62930704795c783e5bf1768a43da6f957108b40873Johnny Chen return false; 63930704795c783e5bf1768a43da6f957108b40873Johnny Chen 64930704795c783e5bf1768a43da6f957108b40873Johnny Chen // A8.6.50 IT 65930704795c783e5bf1768a43da6f957108b40873Johnny Chen unsigned short FirstCond = Bits32(bits7_0, 7, 4); 66930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (FirstCond == 0xF) 67930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 68930704795c783e5bf1768a43da6f957108b40873Johnny Chen printf("Encoding error: IT FirstCond '1111'\n"); 69930704795c783e5bf1768a43da6f957108b40873Johnny Chen return false; 70930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 71930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (FirstCond == 0xE && ITCounter != 1) 72930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 73930704795c783e5bf1768a43da6f957108b40873Johnny Chen printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 74930704795c783e5bf1768a43da6f957108b40873Johnny Chen return false; 75930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 76930704795c783e5bf1768a43da6f957108b40873Johnny Chen 77930704795c783e5bf1768a43da6f957108b40873Johnny Chen ITState = bits7_0; 78930704795c783e5bf1768a43da6f957108b40873Johnny Chen return true; 79930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 80930704795c783e5bf1768a43da6f957108b40873Johnny Chen 81930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Update ITState if necessary. 82930704795c783e5bf1768a43da6f957108b40873Johnny Chenvoid ITSession::ITAdvance() 83930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 84e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton //assert(ITCounter); 85930704795c783e5bf1768a43da6f957108b40873Johnny Chen --ITCounter; 86930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (ITCounter == 0) 87930704795c783e5bf1768a43da6f957108b40873Johnny Chen ITState = 0; 88930704795c783e5bf1768a43da6f957108b40873Johnny Chen else 89930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 90930704795c783e5bf1768a43da6f957108b40873Johnny Chen unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 91930704795c783e5bf1768a43da6f957108b40873Johnny Chen SetBits32(ITState, 4, 0, NewITState4_0); 92930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 93930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 94930704795c783e5bf1768a43da6f957108b40873Johnny Chen 95930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Return true if we're inside an IT Block. 96930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InITBlock() 97930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 98930704795c783e5bf1768a43da6f957108b40873Johnny Chen return ITCounter != 0; 99930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 100930704795c783e5bf1768a43da6f957108b40873Johnny Chen 101c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// Return true if we're the last instruction inside an IT Block. 102c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool ITSession::LastInITBlock() 103c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{ 104c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return ITCounter == 1; 105c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen} 106c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 107930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Get condition bits for the current thumb instruction. 108930704795c783e5bf1768a43da6f957108b40873Johnny Chenuint32_t ITSession::GetCond() 109930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 110c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen if (InITBlock()) 111c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return Bits32(ITState, 7, 4); 112c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen else 113c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return COND_AL; 114930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 115930704795c783e5bf1768a43da6f957108b40873Johnny Chen 11664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// ARM constants used during decoding 11764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define REG_RD 0 11864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define LDM_REGLIST 1 119e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define SP_REG 13 120e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define LR_REG 14 12164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REG 15 12264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REGLIST_BIT 0x8000 12364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 124251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv4 (1u << 0) 12564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv4T (1u << 1) 12664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5T (1u << 2) 12764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TE (1u << 3) 12864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TEJ (1u << 4) 129251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv6 (1u << 5) 13064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6K (1u << 6) 13164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6T2 (1u << 7) 132251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv7 (1u << 8) 13382a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMv7S (1u << 9) 13482a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMv8 (1u << 10) 13564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMvAll (0xffffffffu) 13664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 13782a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 13882a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 13982a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 14082a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 14182a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 14282a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 14382a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 1442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 1454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define No_VFP 0 1464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv1 (1u << 1) 1474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv2 (1u << 2) 1484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv3 (1u << 3) 1494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define AdvancedSIMD (1u << 4) 1504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 1514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 1524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 1534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv2v3 (VFPv2 | VFPv3) 1544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 1550e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1560e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1570e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation 1580e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1590e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1600e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen 1612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize () 1637dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{ 164080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice PluginManager::RegisterPlugin (GetPluginNameStatic (), 165080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice GetPluginDescriptionStatic (), 166080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice CreateInstance); 1672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1687dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen 1692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate () 17164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 172080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice PluginManager::UnregisterPlugin (CreateInstance); 1732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 175080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticeconst char * 176080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstructionARM::GetPluginNameStatic () 177080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{ 178080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return "lldb.emulate-instruction.arm"; 179080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice} 180080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 181080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticeconst char * 182080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstructionARM::GetPluginDescriptionStatic () 183080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{ 184080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return "Emulate instructions for the ARM architecture."; 185080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice} 186080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 187080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstruction * 188888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 189080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{ 190888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 191080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice { 192888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (arch.GetTriple().getArch() == llvm::Triple::arm) 193888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton { 194888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 195888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 196888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (emulate_insn_ap.get()) 197888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return emulate_insn_ap.release(); 198888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton } 199888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 200888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton { 201888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 202888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 203888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (emulate_insn_ap.get()) 204888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return emulate_insn_ap.release(); 205888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton } 206080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice } 207080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 208080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return NULL; 209080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice} 210080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 211080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticebool 212080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 213080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{ 214080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice if (arch.GetTriple().getArch () == llvm::Triple::arm) 215080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return true; 216080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 217080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return true; 218080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 219080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return false; 220080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice} 221080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 222fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 223fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 224fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 225fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 2269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 2289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 229fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 230fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t random_data = rand (); 231fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 232fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 233cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address, random_data, addr_byte_size)) 234fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 235fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 236fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 237fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 238fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 239713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 240713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 241713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n) 242713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 2439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 2459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 246713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 24762ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen bool success; 248713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 249713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 250713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 251713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 252713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 253713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 254713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 255713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 256713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 257713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 258713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 259c07d451bb046e47215bd73fda0235362cc6b1a47Greg Claytonbool 260c07d451bb046e47215bd73fda0235362cc6b1a47Greg ClaytonEmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 261c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton{ 262c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton if (reg_kind == eRegisterKindGeneric) 263c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton { 264c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton switch (reg_num) 265c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton { 266c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 267c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 268c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 269c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 270c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 271c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton default: return false; 272c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton } 273c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton } 274c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 275c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton if (reg_kind == eRegisterKindDWARF) 276c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton return GetARMDWARFRegisterInfo(reg_num, reg_info); 277c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton return false; 278c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton} 279c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 28004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonuint32_t 28104d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonEmulateInstructionARM::GetFramePointerRegisterNumber () const 28204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton{ 283b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton if (m_opcode_mode == eModeThumb) 284b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton { 285b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton switch (m_arch.GetTriple().getOS()) 286b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton { 287b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton case llvm::Triple::Darwin: 288b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton case llvm::Triple::MacOSX: 289b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton case llvm::Triple::IOS: 290b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton return 7; 291b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton default: 292b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton break; 293b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton } 294b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton } 295b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton return 11; 29604d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton} 29704d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton 29804d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonuint32_t 29904d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonEmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 30004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton{ 301b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton if (m_opcode_mode == eModeThumb) 302b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton { 303b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton switch (m_arch.GetTriple().getOS()) 304b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton { 305b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton case llvm::Triple::Darwin: 306b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton case llvm::Triple::MacOSX: 307b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton case llvm::Triple::IOS: 308b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton return dwarf_r7; 309b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton default: 310b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton break; 311b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton } 312b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton } 313b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton return dwarf_r11; 31404d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton} 31504d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton 31608c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to 31708c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates 31808c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data. 3192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 3207bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 32164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 32264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0 32364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton // ARM pseudo code... 32464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (ConditionPassed()) 32564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 32664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton EncodingSpecificOperations(); 32764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton NullCheckIfThumbEE(13); 32864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = SP - 4*BitCount(registers); 32964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 33064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i = 0 to 14) 33164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 332bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (registers<i> == '1') 33364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 33464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 33564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = bits(32) UNKNOWN; 33664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 33764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = R[i]; 33864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = address + 4; 33964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 34064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 34164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 342bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (registers<15> == '1') // Only possible for encoding A1 or A2 34364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = PCStoreValue(); 34464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 34564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton SP = SP - 4*BitCount(registers); 34664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 34764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif 34864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 349107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton bool conditional = false; 35064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 351107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (ConditionPassed(opcode, &conditional)) 35264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 3532b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 354e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 35564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 35664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 3573c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen uint32_t registers = 0; 35891d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 3593c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen switch (encoding) { 360aedde1c6a33b123031499800f56954adc86058f5Johnny Chen case eEncodingT1: 361108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 7, 0); 362aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // The M bit represents LR. 363bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 364ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 14); 365aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 366aedde1c6a33b123031499800f56954adc86058f5Johnny Chen if (BitCount(registers) < 1) 367aedde1c6a33b123031499800f56954adc86058f5Johnny Chen return false; 368aedde1c6a33b123031499800f56954adc86058f5Johnny Chen break; 3697dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT2: 3707dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // Ignore bits 15 & 13. 371108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0) & ~0xa000; 3727dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BitCount(registers) < 2 then UNPREDICTABLE; 3737dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen if (BitCount(registers) < 2) 3747dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 3757dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 3767dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT3: 377108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 3787dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BadReg(t) then UNPREDICTABLE; 37991d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (BadReg(Rt)) 3807dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 38191d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 3827dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 3833c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA1: 384108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0); 385a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // Instead of return false, let's handle the following case as well, 386a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // which amounts to pushing one reg onto the full descending stacks. 387a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 3883c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 3893c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA2: 390108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 3917dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if t == 13 then UNPREDICTABLE; 39291d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt == dwarf_sp) 3933c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen return false; 39491d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 3953c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 396ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 397ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 3983c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen } 399ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 40064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t addr = sp - sp_offset; 40164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton uint32_t i; 40264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 4039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 404107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (conditional) 405107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextRegisterStore; 406107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 407107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextPushRegisterOnStack; 408c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo reg_info; 409c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 410c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 41164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i=0; i<15; ++i) 41264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 4137c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 41464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 415c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 416c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 417e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(i, &success); 41864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 41964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 420cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 42164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 42264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr += addr_byte_size; 42364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 42464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 42564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 4267c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 42764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 428c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 429c9c364f939b95612bedc316b3efbedacc614c855Johnny Chen context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 430e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 43164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 43264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 433e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (!MemAWrite (context, addr, pc, addr_byte_size)) 43464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 43564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 43664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 43764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton context.type = EmulateInstruction::eContextAdjustStackPointer; 4389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 43964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 4402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 44164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 44264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 44364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return true; 44464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 44564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 446ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from 447ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates 448ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data. 4492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 4507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 451ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{ 452ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0 453ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // ARM pseudo code... 454ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (ConditionPassed()) 455ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 456ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(13); 457ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen address = SP; 458ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for i = 0 to 14 459bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 460c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 461bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 462ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if UnalignedAllowed then 463ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemU[address,4]); 464ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen else 465ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemA[address,4]); 466bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<13> == '0' then SP = SP + 4*BitCount(registers); 467bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<13> == '1' then SP = bits(32) UNKNOWN; 468ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 469ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif 470ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 471ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen bool success = false; 472ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 473107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton bool conditional = false; 474107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (ConditionPassed(opcode, &conditional)) 475107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton { 4762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 477e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 478ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 479ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 480ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t registers = 0; 481ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t Rt; // the destination register 482ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen switch (encoding) { 483ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT1: 484ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 7, 0); 485ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // The P bit represents PC. 486bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 487ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 15); 488ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 489ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (BitCount(registers) < 1) 490ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 491ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 492ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT2: 493ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Ignore bit 13. 494ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0) & ~0x2000; 495ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 496bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 497ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 498098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 499098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 500098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 501ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 502ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT3: 503ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 504ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 505098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 13) 506098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 507098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 508ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 509ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 510ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 511ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA1: 512ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0); 513ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Instead of return false, let's handle the following case as well, 514ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // which amounts to popping one reg from the full descending stacks. 515ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 516ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 517bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 518098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 519ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 520ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 521ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA2: 522ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 523ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 then UNPREDICTABLE; 524ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (Rt == dwarf_sp) 525ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 526ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 527ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 528ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen default: 529ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 530ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 531ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 532ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t addr = sp; 533ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t i, data; 534ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 5359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 536107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (conditional) 537107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextRegisterLoad; 538107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 539107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextPopRegisterOffStack; 540c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 541c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 542c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 543c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 544ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for (i=0; i<15; ++i) 545ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 5467c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 547ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 5488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 549cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, 4, 0, &success); 550ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 551ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 552061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 553ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 554ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr += addr_byte_size; 555ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 556ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 557ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 5587c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 559ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 5608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 561cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, 4, 0, &success); 562ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 563ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 564f3eaacfc02d0a98d3bac1eaef74ad5c1c66ccfdcJohnny Chen // In ARMv5T and above, this is an interworking branch. 565668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 566ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 567ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr += addr_byte_size; 568ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 569ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 570ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 5719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 572ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 5732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 574ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 575ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 576ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return true; 577ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen} 578ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 5795b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// Set r7 or ip to point to saved value residing within the stack. 580bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen// ADD (SP plus immediate) 5812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 583bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{ 584bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0 585bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen // ARM pseudo code... 586bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (ConditionPassed()) 587bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 588bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen EncodingSpecificOperations(); 589bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 590bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if d == 15 then 591bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 592bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen else 593bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen R[d] = result; 594bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if setflags then 595bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.N = result<31>; 596bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.Z = IsZeroBit(result); 597bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.C = carry; 598bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.V = overflow; 599bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 600bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#endif 601bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 602bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen bool success = false; 603bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 6047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 605bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 606e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 607bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (!success) 608bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 609bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t Rd; // the destination register 610bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t imm32; 611bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen switch (encoding) { 612bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingT1: 613bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = 7; 614bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 615bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 616bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingA1: 617bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = Bits32(opcode, 15, 12); 618bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 619bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 620bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen default: 621bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 622bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 623bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t sp_offset = imm32; 624bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t addr = sp + sp_offset; // a pointer to the stack area 625bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 6269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 62775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton context.type = eContextSetFramePointer; 628c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 629c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 6309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, sp_offset); 631bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 6322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 633bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 634bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 635bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return true; 636bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen} 637bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 6382ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer. 6392ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register) 6402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 6417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 6422ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{ 6432ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0 6442ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // ARM pseudo code... 6452ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (ConditionPassed()) 6462ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 6472ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen EncodingSpecificOperations(); 6482ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen result = R[m]; 6492ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if d == 15 then 6502ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 6512ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen else 6522ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen R[d] = result; 6532ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if setflags then 6542ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.N = result<31>; 6552ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.Z = IsZeroBit(result); 6562ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.C unchanged 6572ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.V unchanged 6582ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 6592ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif 6602ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 6612ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen bool success = false; 6622ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 6637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6642ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 665e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 6662ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (!success) 6672ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 6682ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen uint32_t Rd; // the destination register 6692ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen switch (encoding) { 6702ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingT1: 6712ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 7; 6722ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 6732ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingA1: 6742ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 12; 6752ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 6762ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen default: 6772ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 6782ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 6799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 6809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 68104d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton if (Rd == GetFramePointerRegisterNumber()) 68204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton context.type = EmulateInstruction::eContextSetFramePointer; 68304d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton else 68404d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton context.type = EmulateInstruction::eContextRegisterPlusOffset; 685c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 686c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 6879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, 0); 6882ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 6892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 6902ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 6912ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 6922ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return true; 6932ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen} 6942ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 6951c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7). 6961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register) 6972b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 6987bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 6991c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{ 7007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdRm (opcode, encoding); 701338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen} 702338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen 703338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register. 704338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register) 705338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool 7067bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 707338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{ 7081c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0 7091c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // ARM pseudo code... 7101c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (ConditionPassed()) 7111c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 7121c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen EncodingSpecificOperations(); 7131c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen result = R[m]; 7141c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if d == 15 then 7151c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen ALUWritePC(result); // setflags is always FALSE here 7161c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen else 7171c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen R[d] = result; 7181c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if setflags then 7191c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.N = result<31>; 7201c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.Z = IsZeroBit(result); 7211c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.C unchanged 7221c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.V unchanged 7231c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 7241c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif 7251c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 7261c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen bool success = false; 7271c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 7287bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7291c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 7301c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rm; // the source register 7311c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rd; // the destination register 732338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen bool setflags; 7331c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen switch (encoding) { 7341c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen case eEncodingT1: 7357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 7361c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen Rm = Bits32(opcode, 6, 3); 737338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = false; 7387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 7397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 740338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen break; 741338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen case eEncodingT2: 7427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 2, 0); 743338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen Rm = Bits32(opcode, 5, 3); 744338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = true; 7457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (InITBlock()) 7467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 7471c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen break; 7487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT3: 7497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 7507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 7517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 7527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 7537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (setflags && (BadReg(Rd) || BadReg(Rm))) 7547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 7557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 7567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 7577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 758ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 75901d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen case eEncodingA1: 76001d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen Rd = Bits32(opcode, 15, 12); 76101d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen Rm = Bits32(opcode, 3, 0); 76201d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen setflags = BitIsSet(opcode, 20); 7631f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 76401d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 76501d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen if (Rd == 15 && setflags) 7661f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 76701d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen break; 7681c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen default: 7691c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 7701c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 7717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = ReadCoreReg(Rm, &success); 7721c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (!success) 7731c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 7741c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 7751c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // The context specifies that Rm is to be moved into Rd. 7769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 7772b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.type = EmulateInstruction::eContextRegisterLoad; 778c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 779c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 7802b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetRegister (dwarf_reg); 781ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 78210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 783ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 7841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 7851c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return true; 7861c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen} 7871c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 788357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register. It 789357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value. 790357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate) 791357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool 7927bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 793357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{ 794357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0 795357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // ARM pseudo code... 796357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if (ConditionPassed()) 797357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 798357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen EncodingSpecificOperations(); 799357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen result = imm32; 800357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if d == 15 then // Can only occur for ARM encoding 801357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen ALUWritePC(result); // setflags is always FALSE here 802357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen else 803357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen R[d] = result; 804357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if setflags then 805357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.N = result<31>; 806357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.Z = IsZeroBit(result); 807357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.C = carry; 808357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // APSR.V unchanged 809357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 810357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif 811357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 8127bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 813357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 814357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t Rd; // the destination register 815357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the immediate value to be written to Rd 81665f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 81765f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen // for setflags == false, this value is a don't care 81865f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen // initialized to 0 to silence the static analyzer 819357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen bool setflags; 820357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen switch (encoding) { 82189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT1: 82289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32(opcode, 10, 8); 82389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = !InITBlock(); 82489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 82589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice carry = APSR_C; 82689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 82789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 82889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 82989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT2: 83089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32(opcode, 11, 8); 83189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = BitIsSet(opcode, 20); 83289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 83389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (BadReg(Rd)) 83489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 83589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 83689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 83789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 83889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT3: 83989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 84089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 84189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 11, 8); 84289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = false; 84389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm4 = Bits32 (opcode, 19, 16); 84489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm3 = Bits32 (opcode, 14, 12); 84589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t i = Bit32 (opcode, 26); 84689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm8 = Bits32 (opcode, 7, 0); 84789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 84889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 84989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if BadReg(d) then UNPREDICTABLE; 85089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (BadReg (Rd)) 85189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 85289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice } 85389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 85489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 85589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingA1: 856061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 85789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 15, 12); 85889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = BitIsSet (opcode, 20); 85989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 8601f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 861061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 8621f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if ((Rd == 15) && setflags) 8631f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 86489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 86589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 86689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 86789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingA2: 86889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 86989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 87089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 15, 12); 87189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = false; 87289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm4 = Bits32 (opcode, 19, 16); 87389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm12 = Bits32 (opcode, 11, 0); 87489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = (imm4 << 12) | imm12; 87589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 87689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if d == 15 then UNPREDICTABLE; 87789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (Rd == 15) 87889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 87989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice } 88089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 88189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 88289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice default: 8839798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen return false; 884357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 885357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t result = imm32; 886357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 887357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // The context specifies that an immediate is to be moved into Rd. 8889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 8899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 8909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 891ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 89210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 893ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 894357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 895357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen return true; 896357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen} 897357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 8985c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 8995c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// register. These 32 bits do not depend on whether the source register values are considered to be signed values or 9005c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// unsigned values. 9015c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// 9025c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 9035c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// limited to only a few forms of the instruction. 9045c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Ticebool 9057bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 9065c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice{ 9075c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#if 0 9085c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ConditionPassed() then 9095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice EncodingSpecificOperations(); 9105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 9115c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 9125c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice result = operand1 * operand2; 9135c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice R[d] = result<31:0>; 9145c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if setflags then 9155c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.N = result<31>; 9165c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.Z = IsZeroBit(result); 9175c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ArchVersion() == 4 then 9185c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.C = bit UNKNOWN; 9195c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // else APSR.C unchanged 9205c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.V always unchanged 9215c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#endif 9225c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9245c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 9255c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t d; 9265c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t n; 9275c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t m; 9285c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice bool setflags; 9295c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9305c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // EncodingSpecificOperations(); 9315c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice switch (encoding) 9325c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 9335c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingT1: 9345c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 9355c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 2, 0); 9365c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 5, 3); 9375c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 2, 0); 9385c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = !InITBlock(); 9395c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9405c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 9415c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((ArchVersion() < ARMv6) && (d == n)) 9425c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9435c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9445c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 9455c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9465c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingT2: 9475c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 9485c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 11, 8); 9495c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 19, 16); 9505c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 3, 0); 9515c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = false; 9525c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9535c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 9545c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (BadReg (d) || BadReg (n) || BadReg (m)) 9555c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9565c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9575c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 9585c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9595c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingA1: 960bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 9615c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 19, 16); 9625c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 3, 0); 9635c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 11, 8); 9645c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = BitIsSet (opcode, 20); 9655c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9665c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 9675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((d == 15) || (n == 15) || (m == 15)) 9685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9695c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 9715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((ArchVersion() < ARMv6) && (d == n)) 9725c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9735c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9745c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 9755c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9765c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice default: 9775c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9785c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 9797bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 9807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 9817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 9825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 9835c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 9845c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!success) 9855c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9865c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9875c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 9885c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 9895c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!success) 9905c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 9915c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9925c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // result = operand1 * operand2; 9935c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t result = operand1 * operand2; 9945c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 9955c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // R[d] = result<31:0>; 996c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo op1_reg; 997c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo op2_reg; 998c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 999c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 10005c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 10015c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice EmulateInstruction::Context context; 1002c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 10035c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice context.SetRegisterRegisterOperands (op1_reg, op2_reg); 10045c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 10055c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 10065c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 10075c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 10085c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if setflags then 10095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (setflags) 10105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 10115c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.N = result<31>; 10125c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.Z = IsZeroBit(result); 1013b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 10145c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 10155c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1016b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_new_inst_cpsr != m_opcode_cpsr) 10175c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 10185c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 10195c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 10205c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 10215c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 10225c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() == 4 then 10235c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.C = bit UNKNOWN; 10245c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 10255c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 10265c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return true; 10275c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice} 10285c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 1029d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1030d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the value. 103128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool 10327bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 103328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{ 103428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0 103528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // ARM pseudo code... 103628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if (ConditionPassed()) 103728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen { 103828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen EncodingSpecificOperations(); 103928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen result = NOT(imm32); 104028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if d == 15 then // Can only occur for ARM encoding 104128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 104228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen else 104328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen R[d] = result; 104428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if setflags then 104528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.N = result<31>; 104628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.Z = IsZeroBit(result); 104728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.C = carry; 104828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // APSR.V unchanged 104928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen } 105028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif 105133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 10527bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 105333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen { 105433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t Rd; // the destination register 1055357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1056357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 105733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen bool setflags; 105833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen switch (encoding) { 105933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingT1: 106033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 11, 8); 106133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 1062d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 106333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 106433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingA1: 106533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 15, 12); 106633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 1067d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 10681f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 1069d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1070d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (Rd == 15 && setflags) 10711f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 107233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 107333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen default: 107433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return false; 107533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 107633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t result = ~imm32; 107733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 107833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen // The context specifies that an immediate is to be moved into Rd. 10799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 10809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 10819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 1082ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 108310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1084ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 108533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 108633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return true; 108728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen} 108828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 1089d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1090d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the result. 1091d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chenbool 10927bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1093d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen{ 1094d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#if 0 1095d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // ARM pseudo code... 1096d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (ConditionPassed()) 1097d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 1098d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EncodingSpecificOperations(); 1099d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1100d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen result = NOT(shifted); 1101d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if d == 15 then // Can only occur for ARM encoding 1102d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ALUWritePC(result); // setflags is always FALSE here 1103d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen else 1104d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen R[d] = result; 1105d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if setflags then 1106d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.N = result<31>; 1107d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.Z = IsZeroBit(result); 1108d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.C = carry; 1109d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // APSR.V unchanged 1110d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 1111d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#endif 1112d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 11137bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1114d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 1115d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rm; // the source register 1116d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rd; // the destination register 1117d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ARM_ShifterType shift_t; 1118d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 1119d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen bool setflags; 1120d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t carry; // the carry bit after the shift operation 1121d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen switch (encoding) { 1122d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT1: 1123d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 2, 0); 1124d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 5, 3); 1125d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = !InITBlock(); 1126d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_t = SRType_LSL; 1127d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_n = 0; 1128d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (InITBlock()) 1129d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1130d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 1131d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT2: 1132d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 11, 8); 1133d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 1134d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 11353dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 1136d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1137ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rm)) 1138d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1139ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 1140d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingA1: 1141d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 15, 12); 1142d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 1143d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 11443dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 1145d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 1146d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen default: 1147d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1148d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 11497bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1150d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t value = ReadCoreReg(Rm, &success); 1151d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!success) 1152d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1153d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1154a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1155a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 1156a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 1157d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t result = ~shifted; 1158d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1159d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // The context specifies that an immediate is to be moved into Rd. 1160d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EmulateInstruction::Context context; 1161d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.type = EmulateInstruction::eContextImmediate; 1162d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.SetNoArgs (); 1163d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1164d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1165d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1166d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 1167d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return true; 1168d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen} 1169d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1170788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register). 1171788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal) 11722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 11737bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1174788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{ 1175788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0 1176788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen // ARM pseudo code... 1177788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (ConditionPassed()) 1178788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 1179788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1180788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen base = Align(PC,4); 1181788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen address = if add then (base + imm32) else (base - imm32); 1182788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen data = MemU[address,4]; 1183788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if t == 15 then 1184bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1185bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 1186788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = data; 1187788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else // Can only apply before ARMv7 1188788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 1189788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = ROR(data, 8*UInt(address<1:0>)); 1190788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else 1191788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = bits(32) UNKNOWN; 1192788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1193788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif 1194788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 11957bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1196788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 11977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1198e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1199788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 1200788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 1201809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen 1202809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen // PC relative immediate load context 12039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 1205c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo pc_reg; 1206c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 12079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 0); 12089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 1209c9de910d61f0471d18fced716fc10681ef432010Johnny Chen uint32_t Rt; // the destination register 1210788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t imm32; // immediate offset from the PC 1211c9de910d61f0471d18fced716fc10681ef432010Johnny Chen bool add; // +imm32 or -imm32? 1212c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t base; // the base address 1213c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t address; // the PC relative address 1214788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t data; // the literal data value from the PC relative load 1215788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen switch (encoding) { 1216788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen case eEncodingT1: 1217c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 10, 8); 1218788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1219c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = true; 1220c9de910d61f0471d18fced716fc10681ef432010Johnny Chen break; 1221c9de910d61f0471d18fced716fc10681ef432010Johnny Chen case eEncodingT2: 1222c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 15, 12); 1223c9de910d61f0471d18fced716fc10681ef432010Johnny Chen imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1224c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = BitIsSet(opcode, 23); 1225098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 1226c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1227788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen break; 1228788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen default: 1229788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 1230788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1231c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1232e39f22d1a369866808b8739c3cec15063d806833Johnny Chen base = Align(pc, 4); 1233c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (add) 1234c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base + imm32; 1235c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 1236c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base - imm32; 1237e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 1238e39f22d1a369866808b8739c3cec15063d806833Johnny Chen context.SetRegisterPlusOffset(pc_reg, address - base); 1239cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 1240788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 1241809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen return false; 1242c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1243c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Rt == 15) 1244c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1245c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Bits32(address, 1, 0) == 0) 1246c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1247c9de910d61f0471d18fced716fc10681ef432010Johnny Chen // In ARMv5T and above, this is an interworking branch. 1248668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 1249c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1250c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1251c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 1252c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1253c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1254c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1255c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1256c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1257c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1258c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1259c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else // We don't handle ARM for now. 1260c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1261c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1262788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1263788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return true; 1264788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen} 1265788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 12665b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP. 1267fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate) 12682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 12697bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1270fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{ 1271fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0 1272fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen // ARM pseudo code... 1273fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (ConditionPassed()) 1274fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 1275fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen EncodingSpecificOperations(); 1276bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1277fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if d == 15 then // Can only occur for ARM encoding 1278fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 1279fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen else 1280fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen R[d] = result; 1281fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if setflags then 1282fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.N = result<31>; 1283fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.Z = IsZeroBit(result); 1284fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.C = carry; 1285fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.V = overflow; 1286fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1287fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif 1288fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1289fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen bool success = false; 1290fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 12917bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1292fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 1293e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1294fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (!success) 1295fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 1296fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen uint32_t imm32; // the immediate operand 1297e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice uint32_t d; 1298e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice bool setflags; 1299e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice switch (encoding) 1300e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1301e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice case eEncodingT1: 1302bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1303e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice d = Bits32 (opcode, 10, 8); 1304e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice setflags = false; 1305e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice imm32 = (Bits32 (opcode, 7, 0) << 2); 1306e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1307e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice break; 1308e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1309e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice case eEncodingT2: 1310bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1311e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice d = 13; 1312e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice setflags = false; 1313e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1314e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1315e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice break; 1316e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1317e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice default: 1318e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1319fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1320fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t sp_offset = imm32; 1321fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1322fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 13239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 13249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 1325c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 1326c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1327080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice context.SetRegisterPlusOffset (sp_reg, sp_offset); 1328fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1329e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (d == 15) 1330e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1331e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (!ALUWritePC (context, addr)) 1332e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1333e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice } 1334e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice else 1335e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1336e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1337e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1338e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice } 1339fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1340fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return true; 1341fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen} 1342fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1343fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP. 13445b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register) 13452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 13467bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 13475b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{ 13485b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0 13495b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen // ARM pseudo code... 13505b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (ConditionPassed()) 13515b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 13525b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen EncodingSpecificOperations(); 13535b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1354bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 13555b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if d == 15 then 13565b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen ALUWritePC(result); // setflags is always FALSE here 13575b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen else 13585b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen R[d] = result; 13595b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if setflags then 13605b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.N = result<31>; 13615b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.Z = IsZeroBit(result); 13625b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.C = carry; 13635b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.V = overflow; 13645b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 13655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif 13665b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 13675b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen bool success = false; 13685b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 13697bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 13705b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 1371e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 13725b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 13735b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 13745b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen uint32_t Rm; // the second operand 13755b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen switch (encoding) { 13765b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen case eEncodingT2: 13775b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen Rm = Bits32(opcode, 6, 3); 13785b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen break; 13795b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen default: 13805b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 13815b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 1382e39f22d1a369866808b8739c3cec15063d806833Johnny Chen int32_t reg_value = ReadCoreReg(Rm, &success); 13835b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 13845b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 13855b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 13865b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 13875b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 13889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1389c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 1390c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 1391c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1392c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 1393c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo other_reg; 1394c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1395080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice context.SetRegisterRegisterOperands (sp_reg, other_reg); 13965b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 13972b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 13985b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 13995b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 14005b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return true; 14015b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen} 14025b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 14039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 14049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or 14059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM. 14069b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate) 14079b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 14087bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 14099b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 14109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 14119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 14129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 14139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 14149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 14159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 14169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC - 4; 14179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 14189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC<31:1> : '1'; 14199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if targetInstrSet == InstrSet_ARM then 14209b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = Align(PC,4) + imm32; 14219b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 14229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = PC + imm32; 14239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen SelectInstrSet(targetInstrSet); 14249b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BranchWritePC(targetAddress); 14259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 14269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 14279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 14287bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = true; 14299b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 14307bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 14319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 14329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 14339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1434e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 14359b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 14369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 143753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t lr; // next instruction address 143853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 14399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen int32_t imm32; // PC-relative offset 14409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 1441d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen case eEncodingT1: 1442d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 1443e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1444bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 1445d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 1446bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1447bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 1448d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 1449d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I1 = !(J1 ^ S); 1450d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I2 = !(J2 ^ S); 145153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1452d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1453e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 1454c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1455098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1456ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1457d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen break; 1458d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen } 14599b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT2: 14609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 1461e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1462bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 14639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10H = Bits32(opcode, 25, 16); 1464bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1465bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 14669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10L = Bits32(opcode, 10, 1); 14679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I1 = !(J1 ^ S); 14689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I2 = !(J2 ^ S); 146953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 14709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1471e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 1472c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1473098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1474ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 14759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 14769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1477c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen case eEncodingA1: 14782b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice lr = pc - 4; // return address 1479c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1480e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 1481c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1482c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen break; 14839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA2: 14842b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice lr = pc - 4; // return address 14859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1486e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 1487c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 14889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 14899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 14909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 14929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 14939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14949ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 14959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 14979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 14989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 14999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 15009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and 15019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register. 15029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register) 15039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 15047bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 15059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 15069b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 15079b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 15089b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 15099b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 15109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 15119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen target = R[m]; 15129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 15139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 4; 15149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = next_instr_addr; 15159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 15169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 2; 1517bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice LR = next_instr_addr<31:1> : '1'; 15189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BXWritePC(target); 15199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 15209b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 15219b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 15229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen bool success = false; 15239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 15247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 15259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 15269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 15279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1528e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 15299b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen addr_t lr; // next instruction address 15309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 15319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 15329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t Rm; // the register with the target address 15339b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 15349b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT1: 1535e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = (pc - 2) | 1u; // return address 15369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 6, 3); 15379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 15389b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 15399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1540098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1541ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 15429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 15439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA1: 1544e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc - 4; // return address 15459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 3, 0); 15469b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 15479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 15489b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1549b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 15509b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 15519b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 15529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1553e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1554ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1555ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1556c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 1557c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 15589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegister (dwarf_reg); 15599b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 15609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1561668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 15629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 15639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 15649b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 15659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 15669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 1567ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1568ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool 15697bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1570ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{ 1571ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0 1572ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // ARM pseudo code... 1573ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (ConditionPassed()) 1574ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 1575ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen EncodingSpecificOperations(); 1576ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen BXWritePC(R[m]); 1577ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1578ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif 1579ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 15807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1581ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 15829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 15839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1584ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen uint32_t Rm; // the register with the target address 1585ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen switch (encoding) { 1586ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingT1: 1587ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 6, 3); 1588098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1589ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1590ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1591ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingA1: 1592ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 3, 0); 1593ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1594ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen default: 1595ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1596ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 15977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1598e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1599ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1600ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1601c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 1602c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 1603c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1604668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetRegister (dwarf_reg); 1605668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 1606ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1607ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1608ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return true; 1609ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen} 1610ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 161159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 161259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// address and instruction set specified by a register as though it were a BX instruction. 161359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// 161459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// TODO: Emulate Jazelle architecture? 161559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 161659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chenbool 16177bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 161859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen{ 161959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#if 0 162059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // ARM pseudo code... 162159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (ConditionPassed()) 162259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 162359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen EncodingSpecificOperations(); 1624bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 162559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen BXWritePC(R[m]); 162659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen else 162759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if JazelleAcceptsExecution() then 162859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen SwitchToJazelleExecution(); 162959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen else 163059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen SUBARCHITECTURE_DEFINED handler call; 163159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 163259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#endif 163359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 16347bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 163559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 163659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen EmulateInstruction::Context context; 163759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 163859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen uint32_t Rm; // the register with the target address 163959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen switch (encoding) { 164059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen case eEncodingT1: 164159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Rm = Bits32(opcode, 19, 16); 164259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (BadReg(Rm)) 164359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 164459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (InITBlock() && !LastInITBlock()) 164559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 164659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen break; 164759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen case eEncodingA1: 164859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Rm = Bits32(opcode, 3, 0); 164959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (Rm == 15) 165059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 165159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen break; 165259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen default: 165359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 165459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 16557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 165659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 165759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (!success) 165859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 165959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 1660c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 1661c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 166259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen context.SetRegister (dwarf_reg); 166359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (!BXWritePC(context, target)) 166459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 166559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 166659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return true; 166759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen} 166859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 16690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset. 16700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate) 16712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 16727bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 16730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 16740d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 16750d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 16760d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 16770d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 16780d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 1679bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 16800d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 16810d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 16820d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 16830d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 16840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 16850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 16860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 16870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 16880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 16890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 16900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 16910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 16927bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 16930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 16947bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1695e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t ip = ReadCoreReg (12, &success); 16960d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 16970d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16980d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 16990d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 17000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 17010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 17020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 17030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 17040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 17050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 17060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t ip_offset = imm32; 17070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = ip - ip_offset; // the adjusted ip value 17080d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 17099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 17109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 1711c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 1712c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 17139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 17140d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 17152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 17160d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 17170d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 17180d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 17190d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 17200d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 17210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset. 17220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate) 17232b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 17247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 17250d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 17260d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 17270d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 17280d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 17290d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 17300d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 1731bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 17320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 17330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 17340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 17350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 17360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 17370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 17380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 17390d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 17400d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 17410d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 17420d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 17430d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 17447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 17450d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 17467bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1747e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 17480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 17490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 17500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 17510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 17520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 17530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 17540d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 17550d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 17560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 17570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 17580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t sp_offset = imm32; 17590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = sp - sp_offset; // the adjusted stack pointer value 17600d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 17619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 17629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 1763c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 1764c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 17659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 17660d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 17672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 17680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 17690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 17700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 17710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 17720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 1773c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// This instruction subtracts an immediate value from the SP value, and writes 1774c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// the result to the destination register. 1775c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// 1776c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 17772b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 17787bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 17794c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{ 17804c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0 17814c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen // ARM pseudo code... 17824c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (ConditionPassed()) 17834c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 17844c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen EncodingSpecificOperations(); 1785bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 178615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if d == 15 then // Can only occur for ARM encoding 1787799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen ALUWritePC(result); // setflags is always FALSE here 17884c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen else 17894c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen R[d] = result; 17904c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if setflags then 17914c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.N = result<31>; 17924c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.Z = IsZeroBit(result); 17934c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.C = carry; 17944c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.V = overflow; 17954c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 17964c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif 17974c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 17984c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen bool success = false; 17997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 18004c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 1801e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 18024c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (!success) 18034c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 1804c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 1805c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen uint32_t Rd; 1806c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen bool setflags; 18074c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen uint32_t imm32; 18084c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen switch (encoding) { 1809e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen case eEncodingT1: 1810c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = 13; 1811c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = false; 1812a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1813ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 181460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT2: 1815c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 11, 8); 1816c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = BitIsSet(opcode, 20); 181760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1818c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 15 && setflags) 18197bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateCMPImm(opcode, eEncodingT2); 1820c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 15 && !setflags) 1821c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen return false; 182260c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 182360c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT3: 1824c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 11, 8); 1825c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = false; 182660c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 182715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15) 182815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 182960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 18304c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen case eEncodingA1: 1831c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 15, 12); 1832c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = BitIsSet(opcode, 20); 183360c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 18341f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 183515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 183615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 18371f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 18384c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen break; 18394c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen default: 18404c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 18414c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 1842c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1843c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 18449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1845c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 13) 1846c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 18472b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 18482b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice // value gets passed down to context.SetImmediateSigned. 1849c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 18502b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetImmediateSigned (-imm64); // the stack pointer offset 1851c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen } 1852c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen else 1853c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 1854c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.type = EmulateInstruction::eContextImmediate; 1855c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.SetNoArgs (); 1856c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen } 1857c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 1858c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 18594c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 18604c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 18614c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return true; 18624c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen} 18634c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 186408c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP. 18652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 18667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1867ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{ 1868ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0 1869ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen // ARM pseudo code... 1870ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (ConditionPassed()) 1871ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1872ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen EncodingSpecificOperations(); 1873ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1874ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen address = if index then offset_addr else R[n]; 1875ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1876ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if wback then R[n] = offset_addr; 1877ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1878ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif 1879ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 1880107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton bool conditional = false; 1881ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen bool success = false; 1882107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (ConditionPassed(opcode, &conditional)) 1883ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 18842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1885e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1886ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1887ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 188891d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 1889ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen uint32_t imm12; 18903e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 18913e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 18923e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool index; 18933e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool add; 18943e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool wback; 1895ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen switch (encoding) { 1896ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen case eEncodingA1: 1897108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 1898108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen imm12 = Bits32(opcode, 11, 0); 18993e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice Rn = Bits32 (opcode, 19, 16); 19003e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 19013e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 19023e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 19033e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 19043e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice index = BitIsSet (opcode, 24); 19053e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice add = BitIsSet (opcode, 23); 19063e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 19073e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 19083e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (wback && ((Rn == 15) || (Rn == Rt))) 19093e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 1910ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen break; 1911ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 1912ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1913ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 19143e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr_t offset_addr; 19153e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (add) 19163e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice offset_addr = sp + imm12; 19173e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice else 19183e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice offset_addr = sp - imm12; 19193e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 19203e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr_t addr; 19213e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (index) 19223e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr = offset_addr; 19233e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice else 19243e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr = sp; 1925ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 19269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1927107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (conditional) 1928107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextRegisterStore; 1929107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 1930107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextPushRegisterOnStack; 1931c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 1932b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton RegisterInfo dwarf_reg; 1933b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton 1934c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1935b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1936b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 193791d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt != 15) 1938ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1939e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(Rt, &success); 1940ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1941ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1942cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1943ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1944ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1945ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen else 1946ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1947e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1948ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1949ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 19508d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemUWrite (context, addr, pc, addr_byte_size)) 1951ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1952ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1953ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 19543e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 19553e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (wback) 19563e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice { 19573e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 19583e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.SetImmediateSigned (addr - sp); 19593e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 19603e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 19613e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice } 1962ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1963ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return true; 1964ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen} 1965ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 196608c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack. 196708c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data. 19682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 19697bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1970799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{ 1971799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0 1972799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // ARM pseudo code... 1973799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (ConditionPassed()) 1974799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 1975799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1976799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = SP - imm32; 1977799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen SP = SP - imm32; 1978799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if single_regs then 1979799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1980799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = S[d+r]; address = address+4; 1981799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen else 1982799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1983799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // Store as two word-aligned words in the correct order for current endianness. 1984799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1985799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1986799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = address+8; 1987799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1988799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif 1989799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1990799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool success = false; 1991107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton bool conditional = false; 1992107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (ConditionPassed(opcode, &conditional)) 1993799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 19942b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1995e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1996799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1997799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1998799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool single_regs; 1999587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2000799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t imm32; // stack offset 2001799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t regs; // number of registers 2002799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen switch (encoding) { 2003799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT1: 2004799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA1: 2005799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = false; 2006bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2007799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2008799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // If UInt(imm8) is odd, see "FSTMX". 2009799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 2010799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2011799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 2012799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 2013799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 2014799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT2: 2015799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA2: 2016799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = true; 2017bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2018799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2019799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0); 2020799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2021799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 2022799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 2023799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 2024799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen default: 2025799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 2026799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 2027799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2028799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2029799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t sp_offset = imm32; 2030799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t addr = sp - sp_offset; 2031799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t i; 2032799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 20339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2034107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (conditional) 2035107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextRegisterStore; 2036107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 2037107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextPushRegisterOnStack; 2038c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 2039c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 2040c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2041bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice for (i=0; i<regs; ++i) 2042799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 2043c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2044bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2045799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // uint64_t to accommodate 64-bit registers. 2046061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2047799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 2048799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 2049cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2050799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 2051799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr += reg_byte_size; 2052799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 2053799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 2054799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 20559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 2056799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 20572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2058799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 2059799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 2060799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return true; 2061799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen} 2062799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 2063587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack. 2064587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data. 2065587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool 20667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2067587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{ 2068587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0 2069587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // ARM pseudo code... 2070587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (ConditionPassed()) 2071587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 2072587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2073587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen address = SP; 2074587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen SP = SP + imm32; 2075587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if single_regs then 2076587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 2077587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen S[d+r] = MemA[address,4]; address = address+4; 2078587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen else 2079587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 2080587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2081587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Combine the word-aligned words in the correct order for current endianness. 2082587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2083587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 2084587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif 2085587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 2086587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool success = false; 2087107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton bool conditional = false; 2088107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (ConditionPassed(opcode, &conditional)) 2089587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 2090587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen const uint32_t addr_byte_size = GetAddressByteSize(); 2091e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 2092587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 2093587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2094587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool single_regs; 2095587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2096587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t imm32; // stack offset 2097587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t regs; // number of registers 2098587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen switch (encoding) { 2099587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT1: 2100587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA1: 2101587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = false; 2102bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2103587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2104587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // If UInt(imm8) is odd, see "FLDMX". 2105587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 2106587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2107587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 2108587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2109587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 2110587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT2: 2111587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA2: 2112587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = true; 2113bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2114587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2115587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0); 2116587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2117587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 2118587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2119587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 2120587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen default: 2121587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2122587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 2123587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2124587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2125587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t sp_offset = imm32; 2126587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t addr = sp; 2127587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t i; 2128587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint64_t data; // uint64_t to accomodate 64-bit registers. 2129587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 21309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2131107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (conditional) 2132107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextRegisterLoad; 2133107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 2134107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextPopRegisterOffStack; 2135c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 2136c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 2137c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2138bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice for (i=0; i<regs; ++i) 2139587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 2140c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2141bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 2142cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, reg_byte_size, 0, &success); 2143587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 2144587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2145061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2146587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2147587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr += reg_byte_size; 2148587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 2149587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 2150587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 21519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 2152587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 2153587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2154587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 2155587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 2156587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return true; 2157587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen} 2158587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 2159b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI) 2160b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool 21617bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2162b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{ 2163b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0 2164b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // ARM pseudo code... 2165b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (ConditionPassed()) 2166b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 2167b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen EncodingSpecificOperations(); 2168b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen CallSupervisor(); 2169b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 2170b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif 2171b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 2172b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen bool success = false; 2173b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 21747bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 2175b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 2176e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 2177b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen addr_t lr; // next instruction address 2178b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!success) 2179b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2180b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t imm32; // the immediate constant 2181b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t mode; // ARM or Thumb mode 2182b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen switch (encoding) { 2183b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingT1: 2184b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = (pc + 2) | 1u; // return address 2185b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 7, 0); 2186b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeThumb; 2187b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 2188b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingA1: 2189b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = pc + 4; // return address 2190b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 23, 0); 2191b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeARM; 2192b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 2193b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen default: 2194b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2195b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 21969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 21979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 21989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextSupervisorCall; 2199c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediate (mode, imm32); 2200b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2201b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2202b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 2203b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return true; 2204b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen} 2205b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 2206c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional. 2207c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool 22087bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2209c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{ 2210c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0 2211c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // ARM pseudo code... 2212c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen EncodingSpecificOperations(); 2213c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen ITSTATE.IT<7:0> = firstcond:mask; 2214c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif 2215c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 2216c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.InitIT(Bits32(opcode, 7, 0)); 2217c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return true; 2218c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen} 2219c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 222004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonbool 222104d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonEmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 222204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton{ 222304d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton // NOP, nothing to do... 222404d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton return true; 222504d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton} 222604d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton 22273b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address. 22283b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool 22297bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 22303b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{ 22313b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0 22323b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // ARM pseudo code... 22333b620b38cd170c20ea607585021ab2ab50286943Johnny Chen if (ConditionPassed()) 22343b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 22353b620b38cd170c20ea607585021ab2ab50286943Johnny Chen EncodingSpecificOperations(); 22363b620b38cd170c20ea607585021ab2ab50286943Johnny Chen BranchWritePC(PC + imm32); 22373b620b38cd170c20ea607585021ab2ab50286943Johnny Chen } 22383b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif 22393b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 22403b620b38cd170c20ea607585021ab2ab50286943Johnny Chen bool success = false; 22413b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 22427bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 22439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 22449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 22459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2246e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 22479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!success) 22489ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 224953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 22509ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen int32_t imm32; // PC-relative offset 22519ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen switch (encoding) { 22529ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT1: 22539ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 22549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2255e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 2256c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 22579ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 22589ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT2: 22599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2260e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 2261c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 22629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 22639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT3: 22649ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 22659ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 2266bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 22679ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm6 = Bits32(opcode, 21, 16); 2268bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 2269bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 22709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 227153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 22729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<21>(imm21); 2273e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 2274c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 22759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 22769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 22779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT4: 22789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 2279bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 22809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 2281bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 2282bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 22839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 22849ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I1 = !(J1 ^ S); 22859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I2 = !(J2 ^ S); 228653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 22879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 2288e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 2289c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 22909ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 22919ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 22929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingA1: 22939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2294e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 2295c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 22969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 22979ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 22989ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 22999ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 23009ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 23019ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 23029ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 23039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return true; 23043b620b38cd170c20ea607585021ab2ab50286943Johnny Chen} 23053b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 230653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 230753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value. They do not affect the condition flags. 230853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ 230953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool 23107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 231153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{ 231253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0 231353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // ARM pseudo code... 231453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen EncodingSpecificOperations(); 231553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if nonzero ^ IsZero(R[n]) then 231653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen BranchWritePC(PC + imm32); 231753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif 231853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 231953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool success = false; 232053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 232153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // Read the register value from the operand register Rn. 2322e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 232353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 232453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 232553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 23269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 23279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2328e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 232953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 233053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 233153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 233253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 233353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm32; // PC-relative offset to branch forward 233453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool nonzero; 233553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen switch (encoding) { 233653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen case eEncodingT1: 2337bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 233853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen nonzero = BitIsSet(opcode, 11); 2339e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 2340c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 234153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen break; 234253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen default: 234353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 234453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen } 234553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (nonzero ^ (reg_val == 0)) 234653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!BranchWritePC(context, target)) 234753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 234853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 234953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 235053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen} 235153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 235260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 235360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 235460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table. 235560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// 235660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 235760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 235860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table. 235960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH 236060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool 23617bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 236260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{ 236360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0 236460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // ARM pseudo code... 236560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(n); 236660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if is_tbh then 236760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 236860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen else 236960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+R[m], 1]); 237060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen BranchWritePC(PC + 2*halfwords); 237160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif 237260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 237360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool success = false; 237460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 237560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rn; // the base register which contains the address of the table of branch lengths 237660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 237760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool is_tbh; // true if table branch halfword 237860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen switch (encoding) { 237960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen case eEncodingT1: 238060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rn = Bits32(opcode, 19, 16); 238160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rm = Bits32(opcode, 3, 0); 238260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen is_tbh = BitIsSet(opcode, 4); 238360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (Rn == 13 || BadReg(Rm)) 238460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 238560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (InITBlock() && !LastInITBlock()) 238660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 238760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen break; 238860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen default: 238960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 239060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen } 239160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 239260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // Read the address of the table from the operand register Rn. 239360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // The PC can be used, in which case the table immediately follows this instruction. 2394e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t base = ReadCoreReg(Rm, &success); 239560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 239660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 239760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 239860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the table index 2399e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t index = ReadCoreReg(Rm, &success); 240060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 240160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 240260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 240360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the offsetted table address 240460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen addr_t addr = base + (is_tbh ? index*2 : index); 240560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 240660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // PC-relative offset to branch forward 240760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EmulateInstruction::Context context; 240860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextTableBranchReadMemory; 2409104c8b69863f229033d616245f56243ca51f1de9Johnny Chen uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 241060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 241160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 241260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 2413e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 241460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 241560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 241660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 241760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // target address 2418e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = pc + offset; 241960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2420c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 242160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 242260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!BranchWritePC(context, target)) 242360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 242460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 242560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return true; 242660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen} 242760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 2428dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// This instruction adds an immediate value to a register value, and writes the result to the destination register. 2429dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// It can optionally update the condition flags based on the result. 2430dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Ticebool 24317bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2432dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice{ 2433dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#if 0 2434dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if ConditionPassed() then 2435dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice EncodingSpecificOperations(); 2436bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2437dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice R[d] = result; 2438dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if setflags then 2439dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.N = result<31>; 2440dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.Z = IsZeroBit(result); 2441dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.C = carry; 2442dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.V = overflow; 2443dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#endif 2444dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2445dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice bool success = false; 2446dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 24477bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 2448dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2449dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t d; 2450dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t n; 2451dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice bool setflags; 2452dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm32; 2453dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t carry_out; 2454dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2455dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //EncodingSpecificOperations(); 2456dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice switch (encoding) 2457dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2458dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT1: 2459dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2460dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 2, 0); 2461dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 5, 3); 2462dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = !InITBlock(); 2463dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = Bits32 (opcode, 8,6); 2464dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2465dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2466dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2467dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT2: 2468dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2469dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 10, 8); 2470dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 10, 8); 2471dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = !InITBlock(); 2472dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = Bits32 (opcode, 7, 0); 2473dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2474dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2475dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2476dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT3: 2477bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2478bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE ADD (SP plus immediate); 2479bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2480dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 11, 8); 2481dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 19, 16); 2482dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = BitIsSet (opcode, 20); 2483dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2484dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2485dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // if BadReg(d) || n == 15 then UNPREDICTABLE; 2486dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (BadReg (d) || (n == 15)) 2487dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2488dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2489dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2490dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2491dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT4: 2492dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2493bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE ADR; 2494bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE ADD (SP plus immediate); 2495dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2496dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 11, 8); 2497dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 19, 16); 2498dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = false; 2499dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t i = Bit32 (opcode, 26); 2500dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm3 = Bits32 (opcode, 14, 12); 2501dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm8 = Bits32 (opcode, 7, 0); 2502dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = (i << 11) | (imm3 << 8) | imm8; 2503dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2504dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // if BadReg(d) then UNPREDICTABLE; 2505dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (BadReg (d)) 2506dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2507dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2508dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2509dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2510dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice default: 2511dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2512dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2513dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2514dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2515dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (!success) 2516dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2517dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2518bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2519dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2520dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2521c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo reg_n; 2522c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2523dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2524dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice EmulateInstruction::Context context; 2525c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 2526dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice context.SetRegisterPlusOffset (reg_n, imm32); 2527dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2528dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //R[d] = result; 2529dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //if setflags then 2530dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.N = result<31>; 2531dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.Z = IsZeroBit(result); 2532dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.C = carry; 2533dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.V = overflow; 2534dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2535dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2536dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2537dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2538dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return true; 2539dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice} 2540dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 25418fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// This instruction adds an immediate value to a register value, and writes the result to the destination 25428fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// register. It can optionally update the condition flags based on the result. 25438fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chenbool 25447bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 25458fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen{ 25468fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#if 0 25478fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // ARM pseudo code... 25488fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if ConditionPassed() then 25498fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EncodingSpecificOperations(); 25508fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 25518fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if d == 15 then 25528fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen ALUWritePC(result); // setflags is always FALSE here 25538fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen else 25548fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen R[d] = result; 25558fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if setflags then 25568fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.N = result<31>; 25578fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.Z = IsZeroBit(result); 25588fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.C = carry; 25598fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.V = overflow; 25608fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#endif 25618fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 25628fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool success = false; 25638fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 25647bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 25658fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 25668fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t Rd, Rn; 25678fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 25688fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool setflags; 25698fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen switch (encoding) 25708fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 25718fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 25728fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 25738fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 25748fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 25758fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 25768fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 25778fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen default: 25788fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 25798fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 25808fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 25818fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // Read the first operand. 2582157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 25838fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!success) 25848fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 25858fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 25868fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 25878fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 25888fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EmulateInstruction::Context context; 2589c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 2590c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 2591c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2592080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, imm32); 25938fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 25948fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 25958fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 25968fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 25978fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return true; 25988fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen} 25998fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 2600d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result 2601d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 260226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 26037bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 260426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 260526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0 260626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // ARM pseudo code... 260726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if ConditionPassed() then 260826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen EncodingSpecificOperations(); 260926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 261026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 261126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if d == 15 then 261226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen ALUWritePC(result); // setflags is always FALSE here 261326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 261426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen R[d] = result; 261526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if setflags then 261626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.N = result<31>; 261726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.Z = IsZeroBit(result); 261826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.C = carry; 261926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.V = overflow; 262026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif 262126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 262226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen bool success = false; 262326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 26247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 262526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 262626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen uint32_t Rd, Rn, Rm; 2627d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen ARM_ShifterType shift_t; 2628d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2629ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen bool setflags; 263026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen switch (encoding) 263126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 2632d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen case eEncodingT1: 2633d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rd = Bits32(opcode, 2, 0); 2634d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rn = Bits32(opcode, 5, 3); 2635d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rm = Bits32(opcode, 8, 6); 2636d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen setflags = !InITBlock(); 2637d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2638d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 2639ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 264026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen case eEncodingT2: 2641bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 264226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen Rm = Bits32(opcode, 6, 3); 2643ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen setflags = false; 2644d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2645d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 264626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (Rn == 15 && Rm == 15) 264726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 2648d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 2649d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen return false; 265026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen break; 26518fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 26528fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 26538fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 26548fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rm = Bits32(opcode, 3, 0); 26558fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 26563dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 26578fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 265826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen default: 265926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 266026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 266126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 266226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the first operand. 2663157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 266426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 266526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 266626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 266726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the second operand. 2668157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 266926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 267026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 267126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 2672a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2673a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 2674a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 26758fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 26769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 26779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2678c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 2679c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo op1_reg; 2680c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo op2_reg; 2681c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2682c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 26838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2684ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 268510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2686ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 268726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 268826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return true; 268926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 269026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 269134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (immediate) adds a register value and an immediate value. 269234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 269334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 26947bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 269534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 269634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 269734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 269834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 269934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 270034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 270134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 270234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 270334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 270434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 270534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 270634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 270734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 270834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 270934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 271034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t imm32; // the immediate value to be compared with 271134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 271234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 2713078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2714078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2715078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15) 2716078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen return false; 2717ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 271834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 271934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 272034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 272134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 272234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 272334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 272434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 272534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from the operand register Rn. 272634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 272734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 272834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 272934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2730078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 273134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 273234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 273334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 273434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs (); 273534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 273634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 273734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 273834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 273934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 274034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 274134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (register) adds a register value and an optionally-shifted register value. 274234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 274334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 27447bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 274534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 274634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 274734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 274834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 274934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 275034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 275134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 275234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 275334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 275434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 275534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 275634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 275734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 275834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 275934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 276034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 276134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rm; // the second operand 276234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 276334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 276434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 276534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 276634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 2, 0); 276734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 5, 3); 276834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 276934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 277034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 277134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT2: 2772078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2773078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rm = Bits32(opcode, 3, 0); 27743dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 2775078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen // if n == 15 || BadReg(m) then UNPREDICTABLE; 2776078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15 || BadReg(Rm)) 277734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 277834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 277934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 278034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 278134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 27823dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 2783ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 278434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 278534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 278634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 278734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rn. 278834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 278934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 279034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 279134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 279234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rm. 279334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 279434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 279534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 279634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2797a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2798a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 2799a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 2800078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 280134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 280234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 280334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 280434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs(); 280534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 280634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 280734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 280834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 280934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 281034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 281134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (immediate) subtracts an immediate value from a register value. 281234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2813d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool 28147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2815d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{ 2816d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0 2817d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // ARM pseudo code... 2818d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if ConditionPassed() then 2819d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen EncodingSpecificOperations(); 2820d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2821d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.N = result<31>; 2822d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.Z = IsZeroBit(result); 2823d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.C = carry; 2824d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.V = overflow; 2825d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif 2826d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2827d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen bool success = false; 2828d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2829d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t Rn; // the first operand 2830d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t imm32; // the immediate value to be compared with 2831d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen switch (encoding) { 2832d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen case eEncodingT1: 2833d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen Rn = Bits32(opcode, 10, 8); 2834d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen imm32 = Bits32(opcode, 7, 0); 2835ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 2836078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen case eEncodingT2: 2837078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2838078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2839078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15) 2840078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen return false; 2841ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 284234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 284334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 284434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2845d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen break; 2846d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen default: 2847d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2848d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen } 2849d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // Read the register value from the operand register Rn. 2850e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 2851d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if (!success) 2852d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2853d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 285410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 285510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 28569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 28579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 28589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 285910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 286010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 286110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2862d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return true; 2863d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen} 2864d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 286534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (register) subtracts an optionally-shifted register value from a register value. 286634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2867e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool 28687bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2869e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{ 2870e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0 2871e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // ARM pseudo code... 2872e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if ConditionPassed() then 2873e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen EncodingSpecificOperations(); 2874e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2875e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2876e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.N = result<31>; 2877e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.Z = IsZeroBit(result); 2878e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.C = carry; 2879e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.V = overflow; 2880e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif 2881e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2882e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen bool success = false; 2883e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2884e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rn; // the first operand 2885e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rm; // the second operand 288634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 288734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2888e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen switch (encoding) { 2889e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT1: 2890e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bits32(opcode, 2, 0); 2891e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 5, 3); 289234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 289334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2894e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 2895e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT2: 2896e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2897e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 6, 3); 289834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 289934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2900e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn < 8 && Rm < 8) 2901e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2902e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn == 15 || Rm == 15) 2903e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2904e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 290534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 290634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 290734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 29083dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 2909ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 2910e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen default: 2911e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2912e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen } 2913e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rn. 291434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 2915e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2916e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 291734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2918e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rm. 291934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 2920e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2921e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2922e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2923a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2924a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 2925a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 292634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 292710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 29289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 29299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 29309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs(); 293110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 293210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 293310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2934e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return true; 2935e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen} 2936e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 293782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 293882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. It can 293982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result. 294082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool 29417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 294282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{ 294382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0 294482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // ARM pseudo code... 294582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if ConditionPassed() then 294682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EncodingSpecificOperations(); 294782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 294882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if d == 15 then // Can only occur for ARM encoding 294982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 295082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen else 295182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen R[d] = result; 295282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if setflags then 295382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.N = result<31>; 295482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.Z = IsZeroBit(result); 295582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.C = carry; 295682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // APSR.V unchanged 295782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif 295882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 29597bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_ASR); 296041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 296141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 296241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 296341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. 296441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update 296541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result. 296641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 29677bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 296841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 296941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 297041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 297141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 297241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 297341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 297441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 297541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 297641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 297741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 297841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 297941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 298041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 298141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 298241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 29837bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_ASR); 298441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 298541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 298641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 298741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 298841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 298941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 29907bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 299141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 299241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 299341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 299441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 299541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 299641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 299741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 299841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 299941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 300041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 300141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 300241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 300341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 300441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 300541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 300641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 300741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 30087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_LSL); 300941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 301041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 301141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits, 301241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 301341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 301441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 301541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 30167bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 301741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 301841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 301941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 302041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 302141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 302241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 302341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 302441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 302541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 302641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 302741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 302841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 302941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 303041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 303141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 30327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_LSL); 303341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 303441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 303541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 303641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 303741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 303841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 30397bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 304041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 304141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 304241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 304341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 304441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 304541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 304641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 304741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 304841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 304941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 305041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 305141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 305241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 305341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 305441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 305541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 305641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 30577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_LSR); 305841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 305941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 306041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits, 306141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 306241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 306341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 306441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 30657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 306641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 306741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 306841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 306941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 307041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 307141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 307241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 307341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 307441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 307541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 307641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 307741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 307841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 307941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 308041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 30817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_LSR); 308241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 308341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 3084eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3085eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3086eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result. 3087eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 30887bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3089eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 3090eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 3091eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 3092eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 3093eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 3094eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3095eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 3096eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 3097eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 3098eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 3099eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 3100eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 3101eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 3102eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 3103eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 3104eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 3105eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 31067bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_ROR); 3107eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 3108eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 3109eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3110eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3111eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3112eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result. 3113eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 31147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3115eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 3116eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 3117eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 3118eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 3119eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 3120eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_n = UInt(R[m]<7:0>); 3121eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3122eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 3123eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 3124eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 3125eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 3126eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 3127eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 3128eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 3129eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 31307bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_ROR); 3131eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 3132eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 3133eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3134eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31]. 3135eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// 3136eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result. 3137eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag. 3138eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 31397bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3140eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 3141eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 3142eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 3143eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 3144eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 3145eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3146eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 3147eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 3148eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 3149eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 3150eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 3151eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 3152eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 3153eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 3154eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 3155eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 3156eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 31577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_RRX); 3158eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 3159eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 316041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 31617bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 316241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 3163e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton// assert(shift_type == SRType_ASR 3164e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton// || shift_type == SRType_LSL 3165e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton// || shift_type == SRType_LSR 3166e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton// || shift_type == SRType_ROR 3167e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton// || shift_type == SRType_RRX); 316841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 316982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool success = false; 317082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 31717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 317282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 3173e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 3174e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the first operand register 3175e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t imm5; // encoding for the shift amount 317682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen uint32_t carry; // the carry bit after the shift operation 317782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool setflags; 3178eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 3179eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Special case handling! 3180eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) -- Encoding T1 31817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton ARMEncoding use_encoding = encoding; 31827bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3183eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 3184eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3185eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // have the same decoding of bit fields as the other Thumb2 shift operations. 31867bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton use_encoding = eEncodingT2; 3187eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen } 3188eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 31897bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton switch (use_encoding) { 319082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT1: 3191eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Due to the above special case handling! 31926cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen if (shift_type == SRType_ROR) 31936cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen return false; 3194eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 319582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 2, 0); 319682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 5, 3); 319782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = !InITBlock(); 319882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 10, 6); 319982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 320082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT2: 3201eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.141 RRX 32026cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen // There's no imm form of RRX instructions. 32036cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen if (shift_type == SRType_RRX) 32046cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen return false; 3205eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 320682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 11, 8); 320782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 320882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 320982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 321082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (BadReg(Rd) || BadReg(Rm)) 321182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 321282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 321382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingA1: 321482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 15, 12); 321582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 321682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 321782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 11, 7); 321882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 321982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen default: 322082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 322182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 322282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3223eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) 3224eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if (shift_type == SRType_ROR && imm5 == 0) 3225eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_type = SRType_RRX; 3226eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 322782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // Get the first operand. 3228e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rm, &success); 322982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (!success) 323082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 323182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3232eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Decode the shift amount if not RRX. 3233eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 323482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3235a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3236a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 3237a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 323882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 323982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // The context specifies that an immediate is to be moved into Rd. 324082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EmulateInstruction::Context context; 324182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 324282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.SetNoArgs (); 324382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 324410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3245ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 324682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 324782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return true; 324882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen} 324982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3250e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool 32517bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3252e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{ 3253e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton // assert(shift_type == SRType_ASR 3254e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton // || shift_type == SRType_LSL 3255e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton // || shift_type == SRType_LSR 3256e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton // || shift_type == SRType_ROR); 3257e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3258e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool success = false; 3259e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 32607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3261e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 3262e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 3263e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rn; // the first operand register 3264e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3265e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t carry; // the carry bit after the shift operation 3266e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool setflags; 3267e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen switch (encoding) { 3268e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT1: 3269e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 2, 0); 3270e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Rd; 3271e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 5, 3); 3272e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = !InITBlock(); 3273e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3274e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT2: 3275e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 11, 8); 3276e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 19, 16); 3277e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 3, 0); 3278e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 3279e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3280e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3281e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3282e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingA1: 3283e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 15, 12); 3284e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 3, 0); 3285e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 11, 8); 3286e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 3287e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (Rd == 15 || Rn == 15 || Rm == 15) 3288e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3289e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3290e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen default: 3291e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3292e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 3293e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3294e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the first operand. 3295e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rn, &success); 3296e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 3297e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3298e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the Rm register content. 3299e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadCoreReg (Rm, &success); 3300e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 3301e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3302e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3303e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the shift amount. 3304e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t amt = Bits32(val, 7, 0); 3305e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3306a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3307a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 3308a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 3309e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3310e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // The context specifies that an immediate is to be moved into Rd. 3311e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen EmulateInstruction::Context context; 3312e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.type = EmulateInstruction::eContextImmediate; 3313e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.SetNoArgs (); 3314e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 331510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3316e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3317e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 3318e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return true; 3319e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen} 3320e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3321b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an 3322713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register. Optionally the address just above the highest of those locations 3323b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register. 3324b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool 33257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3326b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{ 3327b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0 3328b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // ARM pseudo code... 3329b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ConditionPassed() 3330b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3331b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice address = R[n]; 3332b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3333b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for i = 0 to 14 3334b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<i> == '1' then 3335b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice R[i] = MemA[address, 4]; address = address + 4; 3336b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<15> == '1' then 3337b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice LoadWritePC (MemA[address, 4]); 3338b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3339b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3340b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3341b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3342b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif 3343b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3344b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool success = false; 3345107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton bool conditional = false; 3346107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (ConditionPassed(opcode, &conditional)) 3347b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3348b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t n; 3349b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t registers = 0; 3350b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool wback; 3351b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3352b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice switch (encoding) 3353b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3354b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT1: 3355bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3356b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 10, 8); 3357b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 7, 0); 3358b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3359b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsClear (registers, n); 3360b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 3361b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitCount(registers) < 1) 3362b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3363b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3364b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT2: 3365bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101' then SEE POP; 3366bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3367b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 3368b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 3369b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is zero. 3370b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 3371b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3372bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3373b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 3374b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 2) 3375b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3376b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3377b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3378bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3379098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3380b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3381b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3382bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 3383b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback 3384b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice && BitIsSet (registers, n)) 3385b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3386b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3387b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3388b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingA1: 3389b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 3390b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 3391b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 3392b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 3393b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 1)) 3394b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3395b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3396b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice default: 3397b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3398b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3399b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3400b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice int32_t offset = 0; 3401b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3402b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3403b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 340485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 34059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 34069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 3407c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 3408c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 34099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3410b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3411b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for (int i = 0; i < 14; ++i) 3412b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3413b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, i)) 3414b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 341585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 34169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3417b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && (n == 13)) // Pop Instruction 3418107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton { 3419107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (conditional) 3420107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextRegisterLoad; 3421107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 3422107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton context.type = EmulateInstruction::eContextPopRegisterOffStack; 3423107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton } 3424b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3425b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[i] = MemA [address, 4]; address = address + 4; 3426cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3427b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3428b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3429b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3430b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3431b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3432b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3433b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice offset += addr_byte_size; 3434b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3435b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3436b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3437b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, 15)) 3438b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3439b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //LoadWritePC (MemA [address, 4]); 344085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 34419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3442cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3443b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3444b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3445e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3446668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3447b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3448b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3449b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3450b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsClear (registers, n)) 3451b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3452fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // R[n] = R[n] + 4 * BitCount (registers) 3453fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = addr_byte_size * BitCount (registers); 3454fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 34559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3456b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3457b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3458b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3459b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3460b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsSet (registers, n)) 3461b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[n] bits(32) UNKNOWN; 3462713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3463b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3464b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return true; 3465b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice} 3466713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3467bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3468bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// The consecutive memory locations end at this address and the address just below the lowest of those locations 3469bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// can optionally be written back to the base register. 3470713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 34717bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3472713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 3473713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0 3474713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // ARM pseudo code... 3475713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ConditionPassed() then 3476713c2665a27096b68f3f8956222375354f1292f8Caroline Tice EncodingSpecificOperations(); 3477713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 3478713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3479713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for i = 0 to 14 3480bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 3481713c2665a27096b68f3f8956222375354f1292f8Caroline Tice R[i] = MemA[address,4]; address = address + 4; 3482713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3483bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 3484713c2665a27096b68f3f8956222375354f1292f8Caroline Tice LoadWritePC(MemA[address,4]); 3485713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3486bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3487bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3488713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif 3489713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3490713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool success = false; 3491713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 34927bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3493713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3494713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t n; 3495713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t registers = 0; 3496713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool wback; 3497713c2665a27096b68f3f8956222375354f1292f8Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3498713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3499713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // EncodingSpecificOperations(); 3500713c2665a27096b68f3f8956222375354f1292f8Caroline Tice switch (encoding) 3501713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3502713c2665a27096b68f3f8956222375354f1292f8Caroline Tice case eEncodingA1: 3503bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3504713c2665a27096b68f3f8956222375354f1292f8Caroline Tice n = Bits32 (opcode, 19, 16); 3505713c2665a27096b68f3f8956222375354f1292f8Caroline Tice registers = Bits32 (opcode, 15, 0); 3506713c2665a27096b68f3f8956222375354f1292f8Caroline Tice wback = BitIsSet (opcode, 21); 3507b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3508713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3509713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 3510713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3511713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3512713c2665a27096b68f3f8956222375354f1292f8Caroline Tice break; 3513713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3514713c2665a27096b68f3f8956222375354f1292f8Caroline Tice default: 3515713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3516713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3517713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 3518713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3519713c2665a27096b68f3f8956222375354f1292f8Caroline Tice int32_t offset = 0; 3520bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 3521713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3522713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3523713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3524713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3525bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3526713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 35279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 35289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 3529c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 3530c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 35319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3532713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3533713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // for i = 0 to 14 3534713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for (int i = 0; i < 14; ++i) 3535713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3536bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 3537713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, i)) 3538713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3539713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // R[i] = MemA[address,4]; address = address + 4; 3540bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3541cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3542713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3543713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3544713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3545713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3546713c2665a27096b68f3f8956222375354f1292f8Caroline Tice offset += addr_byte_size; 3547713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3548713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3549713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3550bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 3551713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // LoadWritePC(MemA[address,4]); 3552713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, 15)) 3553713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 35549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3555cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3556713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3557713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 355844c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen // In ARMv5T and above, this is an interworking branch. 3559668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3560713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3561713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3562713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3563bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3564713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsClear (registers, n)) 3565713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3566713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3567713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3568fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3569fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3570fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 35719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3572bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 3573713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3574713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3575713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3576713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3577bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3578713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsSet (registers, n)) 3579713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3580713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3581713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 3582713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 3583713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3584713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3585713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3586713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register. 35870b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool 35887bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 35890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{ 35900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0 35910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // ARM pseudo code... 35920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ConditionPassed() then 35930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 35940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice address = R[n] - 4*BitCount(registers); 35950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 35960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for i = 0 to 14 3597bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 35980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice R[i] = MemA[address,4]; address = address + 4; 3599bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 36000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice LoadWritePC(MemA[address,4]); 36010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3602bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3603bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 36040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif 36050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool success = false; 36070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 36090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 36100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t n; 36110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t registers = 0; 36120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool wback; 36130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 36140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice switch (encoding) 36150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 36160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingT1: 3617bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 36180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 36190b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 3620b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is a zero. 36210b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 36220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3623bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 36240b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) 36250b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitCount (registers) < 2) 36260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 36270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36280b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3629bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3630098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 36310b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36320b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3633bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 36340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 36350b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36360b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 36380b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36390b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingA1: 3640bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 36410b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 36420b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 36430b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 36440b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36450b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 36460b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 36470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 36500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice default: 36520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 36540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3655713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers); 3656713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 36570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice int32_t offset = 0; 3658bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3659713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3660713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3661713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3662713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3663bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)); 36649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 36659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 3666c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 3667c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3668bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 36690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36700b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for (int i = 0; i < 14; ++i) 36710b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 36720b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, i)) 36730b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 36740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 3675bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3676cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 36770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 36780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36800b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 36810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 36830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice offset += addr_byte_size; 36840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 36850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 36860b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3687bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 36880b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // LoadWritePC(MemA[address,4]); 36890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, 15)) 36900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 36919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3692cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 36930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 36940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3695e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3696668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 36970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 36980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 36990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3700bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 37010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsClear (registers, n)) 37020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 37030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 37040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3705fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3706fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3707fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 37089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3709bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 37100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 37110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 37120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 37130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3714bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 37150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 3716713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 37170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 37180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return true; 37190b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice} 372085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3721713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3722713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3723713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register. 372485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool 37257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 372685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{ 372785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0 372885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ConditionPassed() then 372985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice EncodingSpecificOperations(); 373085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice address = R[n] + 4; 373185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 373285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for i = 0 to 14 3733bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 373485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice R[i] = MemA[address,4]; address = address + 4; 3735bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 373685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice LoadWritePC(MemA[address,4]); 373785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3738bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3739bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 374085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif 374185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 374285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool success = false; 374385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 37447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 374585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 374685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t n; 374785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t registers = 0; 374885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool wback; 374985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 375085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice switch (encoding) 375185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 375285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice case eEncodingA1: 3753bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 375485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice n = Bits32 (opcode, 19, 16); 375585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice registers = Bits32 (opcode, 15, 0); 375685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice wback = BitIsSet (opcode, 21); 375785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 375885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 375985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 376085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 376185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 376285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice break; 376385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice default: 376485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 376585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 376685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // address = R[n] + 4; 376785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 376885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice int32_t offset = 0; 3769bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3770713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3771713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3772713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3773713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3774bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn + addr_byte_size; 377585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 37769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 37779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 3778c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 3779c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 37809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 378185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 378285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for (int i = 0; i < 14; ++i) 378385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 378485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, i)) 378585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 378685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 378785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3788bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3789cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 379085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 379185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 379285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 379385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 379485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 379585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 379685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice offset += addr_byte_size; 379785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 379885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 379985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3800bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 380185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // LoadWritePC(MemA[address,4]); 380285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, 15)) 380385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 38049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3805cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 380685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 380785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3808e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3809668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 381085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 381185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 381285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3813bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 381485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsClear (registers, n)) 381585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 381685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 381785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3818fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3819fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3820fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 38219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3822bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 382385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 382485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 382585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 382685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3827bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 382885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsSet (registers, n)) 3829713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 383085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 383185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return true; 383285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice} 38330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3834ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and 3835ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register. 3836ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb) 3837ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 38387bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3839ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 3840ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0 3841ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // ARM pseudo code... 3842ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (ConditionPassed()) 3843ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3844ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3845ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3846ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = if index then offset_addr else R[n]; 3847ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen data = MemU[address,4]; 3848ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if wback then R[n] = offset_addr; 3849ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if t == 15 then 3850ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3851ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen elsif UnalignedSupport() || address<1:0> = '00' then 3852ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen R[t] = data; 3853ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3854ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3855ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif 3856ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3857ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool success = false; 3858ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 38597bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3860ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3861ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rt; // the destination register 3862ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rn; // the base register 3863ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t imm32; // the immediate offset used to form the address 3864ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t offset_addr; // the offset address 3865ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t address; // the calculated address 3866ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t data; // the literal data value from memory load 3867ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool add, index, wback; 3868ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen switch (encoding) { 3869baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT1: 387055e569e255b7e1bd510d55820385db2a5ba1426eCaroline Tice Rt = Bits32(opcode, 2, 0); 387155e569e255b7e1bd510d55820385db2a5ba1426eCaroline Tice Rn = Bits32(opcode, 5, 3); 3872baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3873baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE 3874baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3875baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3876baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3877baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3878baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3879baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3880baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT2: 3881bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3882baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 10, 8); 3883baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = 13; 3884baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 3885baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3886baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 3887baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3888baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3889baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3890baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3891baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3892baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3893baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT3: 3894bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 3895baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3896baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 15, 12); 3897baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32 (opcode, 19, 16); 3898baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 11, 0); 3899baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3900baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 3901baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3902baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3903baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3904baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3905baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3906baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3907baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3908baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3909baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3910baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3911baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT4: 3912bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 3913bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3914bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3915bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 3916baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3917baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3918baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3919baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3920baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 15, 12); 3921baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32 (opcode, 19, 16); 3922baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 7, 0); 3923baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3924bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3925baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = BitIsSet (opcode, 10); 3926baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = BitIsSet (opcode, 9); 3927baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = BitIsSet (opcode, 8); 3928baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3929baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3930baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3931baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3932baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3933baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3934baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3935baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice default: 3936baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3937ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3938baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice uint32_t base = ReadCoreReg (Rn, &success); 3939ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3940ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3941ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (add) 3942ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base + imm32; 3943ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3944ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base - imm32; 3945ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3946ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = (index ? offset_addr : base); 3947ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3948c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 3949c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3950ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (wback) 3951ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 39529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context ctx; 3953baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3954baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 39559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 3956ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3957ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3958ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3959ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3960ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Prepare to write to the Rt register. 39619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 3962baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice context.type = EmulateInstruction::eContextRegisterLoad; 3963baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3964ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3965ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Read memory from the address. 3966cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 3967ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3968ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3969ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3970ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Rt == 15) 3971ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3972ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Bits32(address, 1, 0) == 0) 3973ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3974668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3975ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3976ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3977ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3978ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3979ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3980ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3981ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3982ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3983ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3984ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3985ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3986baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice WriteBits32Unknown (Rt); 3987ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3988ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return true; 3989ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 3990ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3991af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3992af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start at this address, and teh address just above the last 3993af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 3994fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 39957bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 3996fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 3997fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0 3998fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ConditionPassed() then 3999fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4000fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = R[n]; 4001fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4002fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for i = 0 to 14 4003bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4004fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 4005fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4006fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 4007fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = R[i]; 4008fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = address + 4; 4009fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4010bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then // Only possible for encoding A1 4011fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = PCStoreValue(); 4012fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 4013fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif 4014fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4015fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool success = false; 4016fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 40177bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4018fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4019fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t n; 4020fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t registers = 0; 4021fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool wback; 4022fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4023fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4024fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4025fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice switch (encoding) 4026fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4027fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT1: 4028bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4029fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 10, 8); 4030fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 7, 0); 4031b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4032fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = true; 4033fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4034fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 4035fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitCount (registers) < 1) 4036fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4037fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4038fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 4039fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4040fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT2: 4041bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4042fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 4043fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 4044b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4045fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 4046fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4047fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4048fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 2)) 4049fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4050fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4051bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 4052fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback && BitIsSet (registers, n)) 4053fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4054fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4055fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 4056fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4057fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingA1: 4058bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4059fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 4060fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 4061fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 4062fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4063fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4064fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 4065fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4066fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4067fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 4068fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4069fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice default: 4070fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4071fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4072fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4073fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = R[n]; 4074fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = 0; 4075fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4076fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 4077fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4078fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 40799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 40809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4081c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 4082c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4083fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4084fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // for i = 0 to 14 4085bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice int lowest_set_bit = 14; 4086fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for (int i = 0; i < 14; ++i) 4087fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4088bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4089fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, i)) 4090fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4091fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (i < lowest_set_bit) 4092fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice lowest_set_bit = i; 4093fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4094fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4095fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4096fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice WriteBits32UnknownToMemory (address + offset); 4097fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 4098fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4099fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = R[i]; 4100fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4101fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 4102fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4103fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4104c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 4105c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 41069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4107cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4108fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4109fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4110fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4111fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = address + 4; 4112fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset += addr_byte_size; 4113fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4114fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4115fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4116bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then // Only possible for encoding A1 4117fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = PCStoreValue(); 4118fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, 15)) 4119fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4120c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo pc_reg; 4121c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 41229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 41238d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4124fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 4125fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4126fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 41278d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4128fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4129fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4130fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4131fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 4132fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback) 4133fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 4134fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 4135fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 41369bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 4137fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr_t data = address + offset; 4138fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4139fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 4140fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4141fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 4142fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 4143fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 4144fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 4145af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4146af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4147af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 41481511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool 41497bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 41501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{ 41511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0 41521511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ConditionPassed() then 41531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EncodingSpecificOperations(); 41541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 41551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for i = 0 to 14 4157bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 41581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 41591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; 41601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 41611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = R[i]; 41621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = address + 4; 41631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4164bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 41651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = PCStoreValue(); 41661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 41681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif 41691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool success = false; 41711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 41731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 41741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t n; 41751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t registers = 0; 41761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool wback; 41771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 41781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // EncodingSpecificOperations(); 41801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice switch (encoding) 41811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 41821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice case eEncodingA1: 4183bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 41841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice n = Bits32 (opcode, 19, 16); 41851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice registers = Bits32 (opcode, 15, 0); 41861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice wback = BitIsSet (opcode, 21); 41871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 41891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 41901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 41911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice break; 41921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice default: 41931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 41941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 41951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 41961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 41971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice int32_t offset = 0; 4198bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 41991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 42001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 42011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4202bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 42031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 42041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EmulateInstruction::Context context; 42051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4206c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 4207c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 42081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 42091511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // for i = 0 to 14 4210bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice int lowest_bit_set = 14; 42111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for (int i = 0; i < 14; ++i) 42121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4213bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 42141511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, i)) 42151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 42161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (i < lowest_bit_set) 42171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice lowest_bit_set = i; 42181511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice //if i == n && wback && i != LowestSetBit(registers) then 42191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((i == n) && wback && (i != lowest_bit_set)) 42201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; 42211511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice WriteBits32UnknownToMemory (address + offset); 42221511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 42231511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 42241511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = R[i]; 42251511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 42261511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 42271511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 42281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4229c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 4230c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4231bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4232cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 42331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 42341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 42351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 42361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = address + 4; 42371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice offset += addr_byte_size; 42381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 42391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 42401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4241bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 42421511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = PCStoreValue(); 42431511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, 15)) 42441511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4245c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo pc_reg; 4246c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 42471511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 42488d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 42491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 42501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 42511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 42528d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 42531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 42541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 42551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 42561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 42571511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (wback) 42581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4259af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 42601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 42611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetImmediateSigned (offset); 4262bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 42631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 42641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 42651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 42661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 42671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return true; 42681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice} 42691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4270af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4271af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end just below this address, and the address of the first of 4272af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register. 4273b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool 42747bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4275b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{ 4276b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0 4277b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ConditionPassed() then 4278b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4279b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = R[n] - 4*BitCount(registers); 4280b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4281b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for i = 0 to 14 4282bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4283b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 4284b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4285b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 4286b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = R[i]; 4287b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = address + 4; 4288b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4289bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then // Only possible for encoding A1 4290b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = PCStoreValue(); 4291b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4292b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 4293b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif 4294b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4295b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4296b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool success = false; 4297b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 42987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4299b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4300b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t n; 4301b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t registers = 0; 4302b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool wback; 4303b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4304b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4305b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4306b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice switch (encoding) 4307b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4308b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingT1: 4309bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101' then SEE PUSH; 4310b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4311b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4312b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See PUSH 4313b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4314bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4315b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 4316b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 4317b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4318b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 4319b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4320b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 2) 4321b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4322bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 4323b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback && BitIsSet (registers, n)) 4324b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4325b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 4326b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4327b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingA1: 4328061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4329b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4330b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4331b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See Push 4332b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4333bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4334b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 4335b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 4336b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 4337b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4338b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 1) 4339b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4340b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 4341b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4342b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice default: 4343b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4344b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4345b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4346b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = R[n] - 4*BitCount(registers); 4347b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4348b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice int32_t offset = 0; 4349bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4350b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4351b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4352b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4353bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4354b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4355b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EmulateInstruction::Context context; 4356b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4357c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 4358c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4359b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4360b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // for i = 0 to 14 4361bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice uint32_t lowest_set_bit = 14; 4362b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for (int i = 0; i < 14; ++i) 4363b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4364bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4365b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, i)) 4366b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4367b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (i < lowest_set_bit) 4368b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice lowest_set_bit = i; 4369b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4370b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4371b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4372b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice WriteBits32UnknownToMemory (address + offset); 4373b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 4374b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4375b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = R[i]; 4376b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4377b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4378b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4379b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4380c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 4381c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4382bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4383cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4384b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4385b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4386b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4387b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = address + 4; 4388b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset += addr_byte_size; 4389b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4390b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4391b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4392bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then // Only possible for encoding A1 4393b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = PCStoreValue(); 4394b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, 15)) 4395b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4396c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo pc_reg; 4397c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4398b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 43998d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4400b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4401b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4402b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 44038d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4404b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4405b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4406b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4407b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 4408b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback) 4409b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4410af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 4411af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 4412af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetImmediateSigned (offset); 4413bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 4414af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4415af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4416af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4417af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4418af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return true; 4419af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice} 4420af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4421af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4422af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start just above this address, and the address of the last 4423af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 4424af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool 44257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4426af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{ 4427af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0 4428af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ConditionPassed() then 4429af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EncodingSpecificOperations(); 4430af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = R[n] + 4; 4431af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4432af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for i = 0 to 14 4433bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4434af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if i == n && wback && i != LowestSetBit(registers) then 4435af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = bits(32) UNKNOWN; 4436af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 4437af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = R[i]; 4438af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = address + 4; 4439af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4440bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 4441af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = PCStoreValue(); 4442af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4443af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 4444af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif 4445af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4446af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool success = false; 4447af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 44487bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4449af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4450af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t n; 4451af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t registers = 0; 4452af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool wback; 4453af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4454af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4455af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // EncodingSpecificOperations(); 4456af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice switch (encoding) 4457af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4458af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice case eEncodingA1: 4459bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4460af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice n = Bits32 (opcode, 19, 16); 4461af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice registers = Bits32 (opcode, 15, 0); 4462af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice wback = BitIsSet (opcode, 21); 4463af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4464af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4465af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((n == 15) && (BitCount (registers) < 1)) 4466af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4467af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice break; 4468af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice default: 4469af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4470af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4471af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = R[n] + 4; 4472af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4473af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice int32_t offset = 0; 4474bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 4475af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4476af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4477af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4478bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn + addr_byte_size; 4479af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4480af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EmulateInstruction::Context context; 4481af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4482c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 4483c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4484af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4485af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t lowest_set_bit = 14; 4486af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // for i = 0 to 14 4487af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for (int i = 0; i < 14; ++i) 4488af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4489bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4490af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, i)) 4491af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4492af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (i < lowest_set_bit) 4493af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice lowest_set_bit = i; 4494af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4495af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4496af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = bits(32) UNKNOWN; 4497af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice WriteBits32UnknownToMemory (address + offset); 4498af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // else 4499af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 4500af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4501af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = R[i]; 4502af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4503af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4504af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4505af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4506c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 4507c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4508bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4509cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4510af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4511af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4512af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4513af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = address + 4; 4514af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset += addr_byte_size; 4515af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4516af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4517af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4518bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 4519af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = PCStoreValue(); 4520af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, 15)) 4521af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4522c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo pc_reg; 4523c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4524af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 45258d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4526af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4527af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4528af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 45298d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4530af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4531af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4532af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4533af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 4534af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (wback) 4535af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4536b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset = addr_byte_size * BitCount (registers); 4537b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 4538b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetImmediateSigned (offset); 4539bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 4540b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4541b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4542b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4543b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4544b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return true; 4545b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice} 45467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 45487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 45497fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool 45507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 45517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{ 45527fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0 45537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ConditionPassed() then 45547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 45557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 45567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = if index then offset_addr else R[n]; 4557bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<1:0> == '00' then 45587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = R[t]; 45597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else // Can only occur before ARMv7 45607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = bits(32) UNKNOWN; 45617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if wback then R[n] = offset_addr; 45627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif 45637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool success = false; 45657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45667bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 45677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 45687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 45697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t t; 45717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t n; 45727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t imm32; 45737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool index; 45747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool add; 45757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool wback; 45767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 45777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice switch (encoding) 45787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 45797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT1: 4580bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 45817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 2, 0); 45827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 5, 3); 45837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 10, 6) << 2; 45847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 45867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 45877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = false; 45887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 45897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 45907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT2: 4592bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 45937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 10, 8); 45947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = 13; 45957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 45967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 45987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 45997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 46007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 46017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 46027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT3: 4604bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 46057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 46067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 46097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 46107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 46117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 11, 0); 46127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 46147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 46157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 46167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 46177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 then UNPREDICTABLE; 46197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (t == 15) 46207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 46227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT4: 4624bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE STRT; 4625bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4626bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 46277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((Bits32 (opcode, 19, 16) == 15) 46287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 46297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 46327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 46337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 46347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0); 46357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4636bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 46377fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = BitIsSet (opcode, 10); 46387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = BitIsSet (opcode, 9); 46397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = BitIsSet (opcode, 8); 46407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 46427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((t == 15) || (wback && (n == t))) 46437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 46457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice default: 46477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 46497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t offset_addr; 46517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t address; 4652b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 46537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4654baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice uint32_t base_address = ReadCoreReg (n, &success); 46557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 46567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (add) 46597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address + imm32; 46607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 46617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address - imm32; 46627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // address = if index then offset_addr else R[n]; 46647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (index) 46657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = offset_addr; 46667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 46677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = base_address; 46687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EmulateInstruction::Context context; 46707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterStore; 4671c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 4672c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 46737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4674bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<1:0> == '00' then 46757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 46767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 46777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = R[t]; 46787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 46797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 46807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4682c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 4683c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 46847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice int32_t offset = address - base_address; 46857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4686cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 46877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 46887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 46897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 46907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 46917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = bits(32) UNKNOWN; 46927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice WriteBits32UnknownToMemory (address); 46937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 46947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 46957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if wback then R[n] = offset_addr; 46967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (wback) 46977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 46987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterLoad; 46997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetAddress (offset_addr); 47007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 47017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 47027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 47037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 47047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return true; 47057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice} 4706af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 47073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 47083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory. The offset register value can optionally be shifted. 47093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool 47107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 47113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{ 47123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0 47133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ConditionPassed() then 47143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 47153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 47163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 47173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = if index then offset_addr else R[n]; 47183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if t == 15 then // Only possible for encoding A1 47193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = PCStoreValue(); 47203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 47213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = R[t]; 4722bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 47233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = data; 47243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else // Can only occur before ARMv7 47253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = bits(32) UNKNOWN; 47263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if wback then R[n] = offset_addr; 47273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif 47283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool success = false; 47303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 47323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 47333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 47343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t t; 47363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t n; 47373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t m; 47383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice ARM_ShifterType shift_t; 47393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t shift_n; 47403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool index; 47413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool add; 47423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool wback; 47433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 47453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice switch (encoding) 47463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 47473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT1: 47483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 47493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 47503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 2, 0); 47513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 5, 3); 47523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 8, 6); 47533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 47553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 47563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 47573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 47583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 47603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 47613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = 0; 47623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 47633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT2: 4765bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 47663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (Bits32 (opcode, 19, 16) == 15) 47673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 47683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 47703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 47713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 47723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 47733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 47753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 47763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 47773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 47783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 47803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 47813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = Bits32 (opcode, 5, 4); 47823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 || BadReg(m) then UNPREDICTABLE; 47843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ((t == 15) || (BadReg (m))) 47853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 47863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 47873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingA1: 47893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 4790bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE STRT; 47913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 47923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 47933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 47943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 47953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4796bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 47973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = BitIsSet (opcode, 24); 47983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = BitIsSet (opcode, 23); 47993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 48003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 48023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t typ = Bits32 (opcode, 6, 5); 48033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 48043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = DecodeImmShift(typ, imm5, shift_t); 48053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if m == 15 then UNPREDICTABLE; 48073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (m == 15) 48083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 48113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback && ((n == 15) || (n == t))) 48123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 48153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 48163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice default: 48173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 48193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t offset_addr; 48213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t address; 48223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice int32_t offset = 0; 48233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 48253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 48263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 48293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 48303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4833a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4834a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 4835a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 48363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 48383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (add) 48393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address + offset; 48403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 48413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address - offset; 48423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // address = if index then offset_addr else R[n]; 48443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (index) 48453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = offset_addr; 48463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 48473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = base_address; 48483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t data; 48503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 then // Only possible for encoding A1 48513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (t == 15) 48523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = PCStoreValue(); 48538d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice data = ReadCoreReg (PC_REG, &success); 48543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 48553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = R[t]; 48563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 48573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 48593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EmulateInstruction::Context context; 48623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterStore; 48633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4864bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 48653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (UnalignedSupport () 48663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || (BitIsClear (address, 1) && BitIsClear (address, 0)) 48673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || CurrentInstrSet() == eModeARM) 48683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 48693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = data; 48703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4871c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 4872c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 48733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4874c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 4875c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 48763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4878cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 48793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 48823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 48833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = bits(32) UNKNOWN; 48843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice WriteBits32UnknownToMemory (address); 48853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback then R[n] = offset_addr; 48873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback) 48883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 48893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterLoad; 48903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetAddress (offset_addr); 48913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 48923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 48933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 48943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 48953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 48963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return true; 48973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice} 489873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 489973a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool 49007bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 490173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{ 490273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0 490373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ConditionPassed() then 490473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 490573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 490673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = if index then offset_addr else R[n]; 490773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice MemU[address,1] = R[t]<7:0>; 490873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if wback then R[n] = offset_addr; 490973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif 491073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 491173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 491273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool success = false; 491373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 49147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 491573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 491673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t t; 491773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t n; 491873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t imm32; 491973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool index; 492073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool add; 492173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool wback; 492273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 492373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice switch (encoding) 492473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 492573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT1: 492673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 492773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 2, 0); 492873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 5, 3); 492973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 10, 6); 493073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 493173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 493273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 493373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 493473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 493573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 493673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 493773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT2: 4938bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 493973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 494073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 494173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 494273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 494373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 494473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 494573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 11, 0); 494673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 494773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 494873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 494973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 495073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 495173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 495273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) then UNPREDICTABLE; 495373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (BadReg (t)) 495473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 495573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 495673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 495773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT3: 4958bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4959bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 496073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 496173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 496273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 496373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 496473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 496573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 496673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 7, 0); 496773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4968bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 496973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = BitIsSet (opcode, 10); 497073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = BitIsSet (opcode, 9); 497173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = BitIsSet (opcode, 8); 497273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 497373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 497473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ((BadReg (t)) || (wback && (n == t))) 497573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 497673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 497773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 497873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice default: 497973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 498073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 498173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 498273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t offset_addr; 498373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t address; 498473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 498573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 498673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 498773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 498873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 498973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (add) 499073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address + imm32; 499173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 499273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address - imm32; 499373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 499473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // address = if index then offset_addr else R[n]; 499573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (index) 499673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = offset_addr; 499773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 499873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = base_address; 499973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 5000cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice // MemU[address,1] = R[t]<7:0> 5001c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 5002c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 500373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 5004c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 5005c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 500673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 500773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EmulateInstruction::Context context; 500873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterStore; 500973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 501073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 501173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 501273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 501373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 501473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 501573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data = Bits32 (data, 7, 0); 501673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 5017cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, 1)) 501873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 501973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 502073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if wback then R[n] = offset_addr; 502173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (wback) 502273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 502373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterLoad; 502473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetAddress (offset_addr); 502573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 502673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 502773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 502873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 502973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 503073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 503173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return true; 503273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice} 50338ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50348ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// STRH (register) calculates an address from a base register value and an offset register value, and stores a 50358ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 50368ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Ticebool 50377bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 50388ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice{ 50398ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#if 0 50408ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if ConditionPassed() then 50418ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 50428ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 50438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 50448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = if index then offset_addr else R[n]; 5045bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> == '0' then 50468ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice MemU[address,2] = R[t]<15:0>; 50478ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else // Can only occur before ARMv7 50488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice MemU[address,2] = bits(16) UNKNOWN; 50498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if wback then R[n] = offset_addr; 50508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#endif 50518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool success = false; 50538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50547bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 50558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 50568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t t; 50578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t n; 50588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t m; 50598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool index; 50608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool add; 50618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool wback; 50628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice ARM_ShifterType shift_t; 50638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t shift_n; 50648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 50668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice switch (encoding) 50678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 50688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingT1: 50698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 50708ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 50718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 2, 0); 50728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 5, 3); 50738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 8, 6); 50748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 50768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = true; 50778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = true; 50788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = false; 50798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 50818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 50828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = 0; 50838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 50858ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50868ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingT2: 5087bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 50888ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 50898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 15, 12); 50908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 19, 16); 50918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 3, 0); 50928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (n == 15) 50938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 50948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 50968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = true; 50978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = true; 50988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = false; 50998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 51018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 51028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = Bits32 (opcode, 5, 4); 51038ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 51058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (BadReg (t) || BadReg (m)) 51068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 51098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingA1: 5111bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE STRHT; 51128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 51138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 15, 12); 51148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 19, 16); 51158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 3, 0); 51168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 5117bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 51188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = BitIsSet (opcode, 24); 51198ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = BitIsSet (opcode, 23); 51208ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 51218ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51228ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 51238ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 51248ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = 0; 51258ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51268ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 51278ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if ((t == 15) || (m == 15)) 51288ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51298ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51308ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 51318ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (wback && ((n == 15) || (n == t))) 51328ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51338ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51348ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 51358ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51368ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice default: 51378ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51388ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 51398ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51408ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 51418ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 51428ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 51458ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 51468ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51478ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5149a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5150a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 5151a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 51528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 51548ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice addr_t offset_addr; 51558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (add) 51568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = Rn + offset; 51578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else 51588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = Rn - offset; 51598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // address = if index then offset_addr else R[n]; 51618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice addr_t address; 51628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (index) 51638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = offset_addr; 51648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else 51658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = Rn; 51668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EmulateInstruction::Context context; 51688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextRegisterStore; 5169c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 5170c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5171c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 5172c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 51738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 5174bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> == '0' then 51758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 51768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 51778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // MemU[address,2] = R[t]<15:0>; 51788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rt = ReadCoreReg (t, &success); 51798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 51808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EmulateInstruction::Context context; 51838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextRegisterStore; 5184c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 5185c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5186c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 5187c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5188c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 5189c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 51908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 51918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 51928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 51938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 51948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 51958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else // Can only occur before ARMv7 51968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 51978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // MemU[address,2] = bits(16) UNKNOWN; 51988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 51998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 52008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if wback then R[n] = offset_addr; 52018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (wback) 52028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 52038ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextAdjustBaseRegister; 52048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetAddress (offset_addr); 52058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 52068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 52078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 52088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 52098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 52108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return true; 52118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice} 52123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 5213157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5214157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// and writes the result to the destination register. It can optionally update the condition flags 5215157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// based on the result. 5216157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 52177bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5218157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 5219157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 5220157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 5221157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 5222157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 5223157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5224157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 5225157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5226157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 5227157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 5228157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 5229157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 5230157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 5231157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 5232157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 5233157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 5234157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5235157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 5236157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 52377bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5238157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5239157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn; 5240157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5241157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 5242157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 5243157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5244157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 5245157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 5246157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5247157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 5248157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5249157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 5250157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5251157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5252157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 5253157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 5254157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5255157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 5256157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 52571f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 5258157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 52591f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 5260157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5261157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 5262157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5263157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5264157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5265157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 5266157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 5267157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5268157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5269157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5270157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5271157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5272157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 5273157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5274157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 5275157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5276157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5277157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5278157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5279157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 5280157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 5281157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5282157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5283157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// register value, and writes the result to the destination register. It can optionally update the 5284157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// condition flags based on the result. 5285157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 52867bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5287157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 5288157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 5289157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 5290157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 5291157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 5292157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5293157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5294157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 5295157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5296157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 5297157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 5298157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 5299157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 5300157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 5301157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 5302157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 5303157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 5304157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5305157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 5306157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 53077bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5308157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5309157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn, Rm; 5310157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ARM_ShifterType shift_t; 5311157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5312157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 5313157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 5314157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5315157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 5316157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5317157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 5, 3); 5318157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = !InITBlock(); 5319157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_t = SRType_LSL; 5320157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = 0; 5321ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 5322157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT2: 5323157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 5324157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5325157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 5326157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 53273dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5328157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5329157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5330157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5331157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 5332157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 5333157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5334157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 5335157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 53363dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 53371f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 5338157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 53391f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 5340157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5341157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 5342157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5343157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5344157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5345157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 5346157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 5347157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5348157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5349157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5350157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the second operand. 5351157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val2 = ReadCoreReg(Rm, &success); 5352157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5353157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5354157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5355a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5356a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 5357a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 5358157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5359157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5360157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 5361157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5362157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 5363157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5364157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5365157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5366157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5367157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 5368157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 5369157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5370a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// This instruction adds an immediate value to the PC value to form a PC-relative address, 5371a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// and writes the result to the destination register. 5372a695f958db37c102d480a9c0780abec262ba8332Johnny Chenbool 53737bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5374a695f958db37c102d480a9c0780abec262ba8332Johnny Chen{ 5375a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#if 0 5376a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // ARM pseudo code... 5377a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if ConditionPassed() then 5378a695f958db37c102d480a9c0780abec262ba8332Johnny Chen EncodingSpecificOperations(); 5379a695f958db37c102d480a9c0780abec262ba8332Johnny Chen result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5380a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if d == 15 then // Can only occur for ARM encodings 5381a695f958db37c102d480a9c0780abec262ba8332Johnny Chen ALUWritePC(result); 5382a695f958db37c102d480a9c0780abec262ba8332Johnny Chen else 5383a695f958db37c102d480a9c0780abec262ba8332Johnny Chen R[d] = result; 5384a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#endif 5385a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5386a695f958db37c102d480a9c0780abec262ba8332Johnny Chen bool success = false; 5387a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 53887bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5389a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 5390a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t Rd; 5391a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5392a695f958db37c102d480a9c0780abec262ba8332Johnny Chen bool add; 5393a695f958db37c102d480a9c0780abec262ba8332Johnny Chen switch (encoding) 5394a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 5395a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT1: 5396a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 10, 8); 5397a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5398a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5399a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT2: 5400a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT3: 5401a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 11, 8); 5402a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5403a695f958db37c102d480a9c0780abec262ba8332Johnny Chen add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5404a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (BadReg(Rd)) 5405a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5406a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5407a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingA1: 5408a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingA2: 5409a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 15, 12); 5410a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5411a695f958db37c102d480a9c0780abec262ba8332Johnny Chen add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5412a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5413a695f958db37c102d480a9c0780abec262ba8332Johnny Chen default: 5414a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5415a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 5416a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5417a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // Read the PC value. 5418a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t pc = ReadCoreReg(PC_REG, &success); 5419a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!success) 5420a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5421a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5422a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5423a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5424a695f958db37c102d480a9c0780abec262ba8332Johnny Chen EmulateInstruction::Context context; 5425a695f958db37c102d480a9c0780abec262ba8332Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5426a695f958db37c102d480a9c0780abec262ba8332Johnny Chen context.SetNoArgs (); 5427a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5428a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!WriteCoreReg(context, result, Rd)) 5429a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5430a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 5431a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return true; 5432a695f958db37c102d480a9c0780abec262ba8332Johnny Chen} 5433a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5434e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5435e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 5436e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 54377bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5438e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 5439e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 5440e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 5441e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 5442e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 5443e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND imm32; 5444e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 5445e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5446e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 5447e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 5448e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 5449e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 5450e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 5451e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 5452e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 5453e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 5454e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5455e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 5456e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 54577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5458e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5459e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn; 5460e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5461e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 5462e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5463e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 5464e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5465e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 5466e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 5467e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5468e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 5469e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5470de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (immediate); 5471e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 54727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTSTImm(opcode, eEncodingT1); 5473e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5474e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5475e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5476e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 5477e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 5478e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5479e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 5480e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 54811f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 5482e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 54831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 5484e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5485e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 5486e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5487e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5488e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5489e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 5490157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5491e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5492e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5493e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5494e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & imm32; 5495e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5496e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 5497e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 5498e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 5499e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5500e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5501e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5502e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5503e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 5504e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 5505e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5506e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5507e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags 5508e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// based on the result. 5509e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 55107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5511e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 5512e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 5513e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 5514e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 5515e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 5516e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5517e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND shifted; 5518e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 5519e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5520e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 5521e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 5522e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 5523e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 5524e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 5525e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 5526e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 5527e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 5528e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5529e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 5530e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 55317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5532e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5533e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn, Rm; 5534e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ARM_ShifterType shift_t; 5535e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5536e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 5537e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; 5538e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 5539e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5540e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 5541e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5542e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 5, 3); 5543e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = !InITBlock(); 5544e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_t = SRType_LSL; 5545e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_n = 0; 5546ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 5547e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT2: 5548e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 5549e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5550e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 5551e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 55523dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5553de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (register); 5554e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 55557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTSTReg(opcode, eEncodingT2); 5556e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5557e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5558e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5559e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 5560e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 5561e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5562e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 5563e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 55643dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 55651f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 5566e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 55671f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 5568e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5569e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 5570e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5571e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5572e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5573e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 5574157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5575e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5576e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5577e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5578e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the second operand. 5579157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 5580e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5581e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5582e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5583a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5584a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 5585a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 5586e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & shifted; 5587e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5588e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 5589e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 5590e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 5591e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5592e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5593e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5594e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5595e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 5596e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 5597e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5598b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5599b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// immediate value, and writes the result to the destination register. It can optionally update the 5600b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// condition flags based on the result. 5601b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool 56027bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5603b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{ 5604b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0 5605b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // ARM pseudo code... 5606b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if ConditionPassed() then 5607b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EncodingSpecificOperations(); 5608b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen result = R[n] AND NOT(imm32); 5609b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if d == 15 then // Can only occur for ARM encoding 5610b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5611b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen else 5612b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen R[d] = result; 5613b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if setflags then 5614b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.N = result<31>; 5615b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.Z = IsZeroBit(result); 5616b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.C = carry; 5617b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // APSR.V unchanged 5618b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif 5619b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5620b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool success = false; 5621b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 56227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5623b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5624b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t Rd, Rn; 5625b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5626b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool setflags; 5627b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5628b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen switch (encoding) 5629b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5630b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT1: 5631b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 11, 8); 5632b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5633b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5634b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5635b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 5636b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5637b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5638b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingA1: 5639b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 15, 12); 5640b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5641b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5642b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 56431f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 5644bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5645b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (Rd == 15 && setflags) 56461f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 5647b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5648b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen default: 5649b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5650b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5651b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5652b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the first operand. 5653b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5654b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5655b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5656b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5657b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t result = val1 & ~imm32; 5658b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5659b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EmulateInstruction::Context context; 5660b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5661b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.SetNoArgs (); 5662b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5663b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5664b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5665b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5666b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return true; 5667b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen} 5668b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5669b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5670b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// optionally-shifted register value, and writes the result to the destination register. 5671b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// It can optionally update the condition flags based on the result. 5672b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool 56737bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5674b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{ 5675b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0 5676b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // ARM pseudo code... 5677b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if ConditionPassed() then 5678b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EncodingSpecificOperations(); 5679b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5680b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen result = R[n] AND NOT(shifted); 5681b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if d == 15 then // Can only occur for ARM encoding 5682b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5683b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen else 5684b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen R[d] = result; 5685b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if setflags then 5686b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.N = result<31>; 5687b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.Z = IsZeroBit(result); 5688b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.C = carry; 5689b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // APSR.V unchanged 5690b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif 5691b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5692b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool success = false; 5693b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 56947bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5695b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5696b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t Rd, Rn, Rm; 5697b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ARM_ShifterType shift_t; 5698b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5699b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool setflags; 5700b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t carry; 5701b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen switch (encoding) 5702b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5703b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT1: 5704b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5705b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 5, 3); 5706b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = !InITBlock(); 5707b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_t = SRType_LSL; 5708b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = 0; 5709b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5710b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT2: 5711b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 11, 8); 5712b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5713b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 3, 0); 5714b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5715b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5716b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5717b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5718b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5719b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingA1: 5720b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 15, 12); 5721b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5722b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 3, 0); 5723b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5724b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 57251f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 5726bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5727b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (Rd == 15 && setflags) 57281f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 5729b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5730b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen default: 5731b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5732b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5733b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5734b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the first operand. 5735b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5736b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5737b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5738b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5739b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the second operand. 5740b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 5741b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5742b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5743b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5744a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5745a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 5746a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 5747b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t result = val1 & ~shifted; 5748b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5749b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EmulateInstruction::Context context; 5750b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5751b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.SetNoArgs (); 5752b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5753b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5754b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5755b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5756b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return true; 5757b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen} 5758b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 57594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5760e92b27c9262fd185359e6e2184b20d08953485f4Johnny Chen// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 57614d729c559d039181f250e0e3cd444fa73638f26fCaroline Ticebool 57627bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 57634d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice{ 57644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#if 0 57654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if ConditionPassed() then 57664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EncodingSpecificOperations(); 57674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 57684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = if index then offset_addr else R[n]; 57694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = MemU[address,4]; 57704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if wback then R[n] = offset_addr; 57714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if t == 15 then 5772bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5773bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 57744d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = data; 57754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else // Can only apply before ARMv7 57764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 57774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#endif 57784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 57794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool success = false; 57804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 57817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 57824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 57834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 57844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 57854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t t; 57864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t n; 57874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t imm32; 57884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool index; 57894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool add; 57904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool wback; 57914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 57924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice switch (encoding) 57934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 57944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice case eEncodingA1: 5795bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 5796bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRT; 5797bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 57984d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 57994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice t = Bits32 (opcode, 15, 12); 58004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice n = Bits32 (opcode, 19, 16); 58014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice imm32 = Bits32 (opcode, 11, 0); 58024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5803bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5804bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice index = BitIsSet (opcode, 24); 5805bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice add = BitIsSet (opcode, 23); 5806bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 58074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback && n == t then UNPREDICTABLE; 58094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback && (n == t)) 58104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice break; 58134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice default: 58154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 58174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t address; 58194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t offset_addr; 58208d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice addr_t base_address = ReadCoreReg (n, &success); 58214d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 58224d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 58254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (add) 58268d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice offset_addr = base_address + imm32; 58274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 58284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = base_address - imm32; 58294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // address = if index then offset_addr else R[n]; 58314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (index) 58324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = offset_addr; 58334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 58344d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = base_address; 58354d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58364d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // data = MemU[address,4]; 58374d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5838c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 5839c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 58404d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58414d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EmulateInstruction::Context context; 58424d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 58434d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 58444d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58454d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 58464d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 58474d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58484d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58494d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback then R[n] = offset_addr; 58504d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback) 58514d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 58524d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextAdjustBaseRegister; 58534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetAddress (offset_addr); 58544d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 58554d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58564d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 58574d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58584d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if t == 15 then 58594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (t == 15) 58604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 5861bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 58624d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 58634d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 58644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // LoadWritePC (data); 58654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 58664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 58674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice LoadWritePC (context, data); 58684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 58694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 58704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 5872bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // elsif UnalignedSupport() || address<1:0> = '00' then 58734d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 58744d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 58754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = data; 58764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 58774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 58784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 58794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 58814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // else // Can only apply before ARMv7 58824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 58834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 58844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 5885a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen data = ROR (data, Bits32 (address, 1, 0), &success); 5886a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 5887a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 58884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 58894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetImmediate (data); 58904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 58914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 58924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 58934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 58944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 58954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return true; 58964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice} 58974d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5898fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5899fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5900fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Ticebool 59017bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5902fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice{ 5903fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#if 0 5904fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ConditionPassed() then 5905fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5906fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 5907fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5908fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = if index then offset_addr else R[n]; 5909fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = MemU[address,4]; 5910fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if wback then R[n] = offset_addr; 5911fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if t == 15 then 5912bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5913bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 5914fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = data; 5915fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 5916fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if CurrentInstrSet() == InstrSet_ARM then 5917fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 5918fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5919fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = bits(32) UNKNOWN; 5920fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#endif 5921fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5922fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool success = false; 5923fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 59247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5925fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5926fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 5927fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5928fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t t; 5929fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t n; 5930fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t m; 5931fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool index; 5932fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool add; 5933fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool wback; 5934fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice ARM_ShifterType shift_t; 5935fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t shift_n; 5936fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5937fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice switch (encoding) 5938fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5939fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT1: 5940fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5941fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5942fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 2, 0); 5943fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 5, 3); 5944fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 8, 6); 5945fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5946fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5947fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5948fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5949fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5950fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5951fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 5952fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5953fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = 0; 5954fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5955fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5956fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5957fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT2: 5958bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 5959fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5960fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5961fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5962fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5963fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5964fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5965fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5966fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5967fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5968fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5969fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5970fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5971fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = Bits32 (opcode, 5, 4); 5972fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5973fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if BadReg(m) then UNPREDICTABLE; 5974fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BadReg (m)) 5975fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5976fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5977fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5978fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ((t == 15) && InITBlock() && !LastInITBlock()) 5979fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5980fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5981fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5982fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5983fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingA1: 5984fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5985bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRT; 5986fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5987fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5988fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5989fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5990fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5991bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5992fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = BitIsSet (opcode, 24); 5993fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = BitIsSet (opcode, 23); 5994fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5995fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5996fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5997fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 5998fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 5999fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 6000fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6001fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if m == 15 then UNPREDICTABLE; 6002fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (m == 15) 6003fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6004fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6005fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6006fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback && ((n == 15) || (n == t))) 6007fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6008fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6009fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 6010fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6011fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6012fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice default: 6013fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6014fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6015fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6016fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6017fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 6018fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6019fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6020fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6021fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 6022fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6023fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6024fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t offset_addr; 6025fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t address; 6026fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6027fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6028a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6029a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 6030a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 6031fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6032fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6033fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (add) 6034fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn + offset; 6035fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 6036fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn - offset; 6037fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6038fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // address = if index then offset_addr else R[n]; 6039fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (index) 6040fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = offset_addr; 6041fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 6042fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = Rn; 6043fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6044fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // data = MemU[address,4]; 6045c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 6046c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6047fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6048fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EmulateInstruction::Context context; 6049fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 6050fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 6051fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6052fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6053fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 6054fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6055fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6056fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback then R[n] = offset_addr; 6057fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback) 6058fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6059fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextAdjustBaseRegister; 6060fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetAddress (offset_addr); 6061fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6062fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6063fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6064fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6065fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 then 6066fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (t == 15) 6067fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6068bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6069fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6070fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6071fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 6072fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 6073fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice LoadWritePC (context, data); 6074fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6075fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 6076fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6077fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6078bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // elsif UnalignedSupport() || address<1:0> = '00' then 6079fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6080fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6081fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = data; 6082fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 6083fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 6084fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6085fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6086fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6087fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 6088fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6089fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ARM then 6090fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (CurrentInstrSet () == eModeARM) 6091fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6092fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 6093a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen data = ROR (data, Bits32 (address, 1, 0), &success); 6094a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 6095a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 6096fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 6097fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetImmediate (data); 6098fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6099fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 6100fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6101fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 6102fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 6103fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = bits(32) UNKNOWN; 6104fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice WriteBits32Unknown (t); 6105fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6106fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6107fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 6108fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return true; 6109fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice} 611021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 611121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice// LDRB (immediate, Thumb) 611221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Ticebool 61137bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 611421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice{ 611521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#if 0 611621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if ConditionPassed() then 611721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 611821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 611921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = if index then offset_addr else R[n]; 612021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 612121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if wback then R[n] = offset_addr; 612221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#endif 612321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 612421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool success = false; 612521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 61267bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 612721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 612821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t t; 612921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t n; 613021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t imm32; 613121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool index; 613221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool add; 613321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool wback; 613421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 613521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 613621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice switch (encoding) 613721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 613821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT1: 613921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 614021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 2, 0); 614121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 5, 3); 614221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 10, 6); 614321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 614421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 614521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 614621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 614721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback= false; 614821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 614921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 615021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 615121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT2: 6152bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6153bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 615421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 615521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 615621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 615721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 11, 0); 615821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 615921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 616021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 616121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 616221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = false; 616321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 616421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if t == 13 then UNPREDICTABLE; 616521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (t == 13) 616621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 616721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 616821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 616921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 617021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT3: 6171bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6172bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 6173bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6174bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 617521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 617621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 617721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 617821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 617921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 618021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 618121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 7, 0); 618221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 6183bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 618421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = BitIsSet (opcode, 10); 618521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = BitIsSet (opcode, 9); 618621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = BitIsSet (opcode, 8); 618721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 618821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 618921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BadReg (t) || (wback && (n == t))) 619021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 619121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 619221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 619321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 619421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice default: 619521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 619621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 619721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 619821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 619921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 620021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 620121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 620221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t address; 620321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t offset_addr; 620421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 620521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 620621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (add) 620721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn + imm32; 620821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 620921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn - imm32; 621021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 621121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // address = if index then offset_addr else R[n]; 621221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (index) 621321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = offset_addr; 621421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 621521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = Rn; 621621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 621721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 6218c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 6219c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 6220c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6221c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 622221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 622321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EmulateInstruction::Context context; 622421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextRegisterLoad; 622521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 622621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 622721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 622821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 622921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 623021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 623121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 623221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 623321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 623421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if wback then R[n] = offset_addr; 623521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (wback) 623621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 623721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextAdjustBaseRegister; 623821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetAddress (offset_addr); 623921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 624021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 624121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 624221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 624321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return true; 624421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice} 6245f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6246f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6247f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// zero-extends it to form a 32-bit word and writes it to a register. 6248f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Ticebool 62497bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6250f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice{ 6251f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#if 0 6252f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if ConditionPassed() then 6253f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6254f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice base = Align(PC,4); 6255f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = if add then (base + imm32) else (base - imm32); 6256f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 6257f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#endif 6258f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6259f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool success = false; 6260f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 62617bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6262f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 6263f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t t; 6264f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t imm32; 6265f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool add; 6266f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice switch (encoding) 6267f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 6268f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingT1: 6269bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6270bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6271f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 6272f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6273f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 6274f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6275f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 13 then UNPREDICTABLE; 6276f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 13) 6277f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6278f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6279f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 6280f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6281f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingA1: 6282bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6283f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 6284f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6285f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 6286f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6287f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 15 then UNPREDICTABLE; 6288f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 15) 6289f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6290f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 6291f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6292f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice default: 6293f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6294f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 6295f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6296f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // base = Align(PC,4); 62978d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6298f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 6299f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6300f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6301f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t base = AlignPC (pc_val); 6302f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6303f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice addr_t address; 6304f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // address = if add then (base + imm32) else (base - imm32); 6305f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (add) 6306f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base + imm32; 6307f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice else 6308f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base - imm32; 6309f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6310f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 6311f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EmulateInstruction::Context context; 6312f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.type = eContextRelativeBranchImmediate; 6313f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.SetImmediate (address - base); 6314f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6315f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 6316f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 6317f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6318f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6319f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6320f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6321f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 6322f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return true; 6323f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice} 632430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 632530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 632630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 632730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// optionally be shifted. 632830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Ticebool 63297bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 633030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice{ 633130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#if 0 633230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ConditionPassed() then 633330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 633430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 633530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 633630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = if index then offset_addr else R[n]; 633730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice R[t] = ZeroExtend(MemU[address,1],32); 633830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if wback then R[n] = offset_addr; 633930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#endif 634030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 634130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool success = false; 634230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 63437bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 634430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 634530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t t; 634630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t n; 634730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t m; 634830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool index; 634930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool add; 635030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool wback; 635130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice ARM_ShifterType shift_t; 635230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t shift_n; 635330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 635430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 635530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice switch (encoding) 635630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 635730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT1: 635830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 635930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 2, 0); 636030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 5, 3); 636130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 8, 6); 636230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 636330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 636430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 636530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 636630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 636730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 636830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 636930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 637030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = 0; 637130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 637230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 637330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT2: 6374bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6375bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 637630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 637730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 637830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 637930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 638030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 638130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 638230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 638330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 638430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 638530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 638630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 638730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 638830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = Bits32 (opcode, 5, 4); 638930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 639030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 639130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 13) || BadReg (m)) 639230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 639330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 639430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 639530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingA1: 639630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 6397bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRBT; 639830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 639930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 640030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 640130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 640230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 6403bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 640430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = BitIsSet (opcode, 24); 640530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = BitIsSet (opcode, 23); 640630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 640730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 640830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 640930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 641030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 641130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 641230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 641330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 641430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 15) || (m == 15)) 641530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 641630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 641730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 641830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback && ((n == 15) || (n == t))) 641930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 642030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 642130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 642230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 642330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice default: 642430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 642530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 642630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 642730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset_addr; 642830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t address; 642930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 643030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 643130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 643230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 643330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 643430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 6435a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6436a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 6437a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 643830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 643930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 644030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 644130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 644230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 644330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 644430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (add) 644530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn + offset; 644630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 644730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn - offset; 644830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 644930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // address = if index then offset_addr else R[n]; 645030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (index) 645130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = offset_addr; 645230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 645330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = Rn; 645430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 645530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // R[t] = ZeroExtend(MemU[address,1],32); 6456c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 6457c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 645830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 645930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EmulateInstruction::Context context; 646030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextRegisterLoad; 646130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 646230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 646330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 646430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 646530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 646630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 646730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 646830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 646930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 647030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback then R[n] = offset_addr; 647130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback) 647230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 647330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextAdjustBaseRegister; 647430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetAddress (offset_addr); 647530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 647630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 647730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 647830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 647930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return true; 648030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice} 64810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 64820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 64830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 64840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// post-indexed, or pre-indexed addressing. 64850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Ticebool 64867bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 64870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice{ 64880491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#if 0 64890491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if ConditionPassed() then 64900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 64910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 64920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = if index then offset_addr else R[n]; 64930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice data = MemU[address,2]; 64940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if wback then R[n] = offset_addr; 6495bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 64960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice R[t] = ZeroExtend(data, 32); 64970491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else // Can only apply before ARMv7 64980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice R[t] = bits(32) UNKNOWN; 64990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#endif 65000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool success = false; 65030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 65050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 65060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t t; 65070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t n; 65080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t imm32; 65090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool index; 65100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool add; 65110491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool wback; 65120491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 65140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice switch (encoding) 65150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 65160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT1: 6517bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 65180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 2, 0); 65190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 5, 3); 65200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 10, 6) << 1; 65210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 65230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = true; 65240491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = true; 65250491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = false; 65260491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65270491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 65280491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65290491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT2: 6530bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 6531bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 65320491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 65330491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 15, 12); 65340491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 19, 16); 65350491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 11, 0); 65360491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65370491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 65380491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = true; 65390491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = true; 65400491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = false; 65410491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65420491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if t == 13 then UNPREDICTABLE; 65430491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (t == 13) 65440491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 65450491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 65460491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65470491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT3: 6548bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 6549bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6550bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6551bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 65520491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 65530491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 65540491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65550491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 65560491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 15, 12); 65570491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 19, 16); 65580491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 7, 0); 65590491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 6560bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 65610491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = BitIsSet (opcode, 10); 65620491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = BitIsSet (opcode, 9); 65630491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = BitIsSet (opcode, 8); 65640491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65650491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 65660491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (BadReg (t) || (wback && (n == t))) 65670491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 65680491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 65690491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65700491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice default: 65710491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 65720491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 65730491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65740491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 65750491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 65760491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!success) 65770491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 65780491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65790491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice addr_t offset_addr; 65800491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice addr_t address; 65810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (add) 65830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = Rn + imm32; 65840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else 65850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = Rn - imm32; 65860491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // address = if index then offset_addr else R[n]; 65880491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (index) 65890491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = offset_addr; 65900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else 65910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = Rn; 65920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // data = MemU[address,2]; 6594c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 6595c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 65960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 65970491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice EmulateInstruction::Context context; 65980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextRegisterLoad; 65990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 66000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 66010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 66020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!success) 66030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 66040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 66050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if wback then R[n] = offset_addr; 66060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (wback) 66070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 66080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextAdjustBaseRegister; 66090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetAddress (offset_addr); 66100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 66110491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 66120491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 66130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 6614bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 66150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (UnalignedSupport () || BitIsClear (address, 0)) 66160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 66170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // R[t] = ZeroExtend(data, 32); 66180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextRegisterLoad; 66190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 66200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 66210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 66220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 66230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else // Can only apply before ARMv7 66240491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 66250491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // R[t] = bits(32) UNKNOWN; 66260491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice WriteBits32Unknown (t); 66270491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 66280491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 66290491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return true; 66300491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice} 6631fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6632952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6633952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// zero-extends it to form a 32-bit word, and writes it to a register. 6634952b53892191222c56003cd60d8a4a71c4384aa7Caroline Ticebool 66357bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6636952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice{ 6637952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#if 0 6638952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if ConditionPassed() then 6639952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6640952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice base = Align(PC,4); 6641952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = if add then (base + imm32) else (base - imm32); 6642952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice data = MemU[address,2]; 6643bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 6644952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice R[t] = ZeroExtend(data, 32); 6645952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else // Can only apply before ARMv7 6646952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice R[t] = bits(32) UNKNOWN; 6647952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#endif 66480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6649952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice bool success = false; 6650952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 66517bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6652952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6653952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t t; 6654952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm32; 6655952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice bool add; 6656952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6657952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6658952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice switch (encoding) 6659952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6660952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice case eEncodingT1: 6661bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 6662bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6663952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice t = Bits32 (opcode, 15, 12); 6664952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6665952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice add = BitIsSet (opcode, 23); 6666952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6667952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // if t == 13 then UNPREDICTABLE; 6668952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (t == 13) 6669952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6670952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6671952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice break; 6672952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6673952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice case eEncodingA1: 6674952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6675952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 6676952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 6677952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6678bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6679952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice t = Bits32 (opcode, 15, 12); 668040b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 6681952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice add = BitIsSet (opcode, 23); 6682952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6683952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // if t == 15 then UNPREDICTABLE; 6684952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (t == 15) 6685952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6686952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice break; 6687952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6688952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6689952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice default: 6690952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6691952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6692952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6693952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // base = Align(PC,4); 66948d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6695952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!success) 6696952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6697952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6698952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice addr_t base = AlignPC (pc_value); 6699952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice addr_t address; 6700952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6701952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // address = if add then (base + imm32) else (base - imm32); 6702952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (add) 6703952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = base + imm32; 6704952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else 6705952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = base - imm32; 6706952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6707952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // data = MemU[address,2]; 6708c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 6709c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6710952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6711952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice EmulateInstruction::Context context; 6712952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.type = eContextRegisterLoad; 6713952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 6714952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6715952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 6716952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!success) 6717952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6718952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6719952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6720bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 6721952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (UnalignedSupport () || BitIsClear (address, 0)) 6722952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6723952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // R[t] = ZeroExtend(data, 32); 6724952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.type = eContextRegisterLoad; 6725952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 6726952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6727952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6728952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6729952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6730952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else // Can only apply before ARMv7 6731952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6732952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // R[t] = bits(32) UNKNOWN; 6733952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice WriteBits32Unknown (t); 6734952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6735952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6736952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return true; 6737952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice} 6738952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 67390e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 67400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 67410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// be shifted left by 0, 1, 2, or 3 bits. 67420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Ticebool 67437bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 67440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice{ 67450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#if 0 67460e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ConditionPassed() then 67470e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 67480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 67490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 67500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = if index then offset_addr else R[n]; 67510e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice data = MemU[address,2]; 67520e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if wback then R[n] = offset_addr; 6753bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 67540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice R[t] = ZeroExtend(data, 32); 67550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else // Can only apply before ARMv7 67560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice R[t] = bits(32) UNKNOWN; 67570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#endif 67580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool success = false; 67600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67617bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 67620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 67630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t t; 67640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t n; 67650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t m; 67660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool index; 67670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool add; 67680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool wback; 67690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice ARM_ShifterType shift_t; 67700e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t shift_n; 67710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 67730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice switch (encoding) 67740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 67750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingT1: 67760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 67770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 67780e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 2, 0); 67790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 5, 3); 67800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 8, 6); 67810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 67830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = true; 67840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = true; 67850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = false; 67860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67870e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 67880e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 67890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = 0; 67900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 67920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 67930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingT2: 6794bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 6795bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 67960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 67970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 15, 12); 67980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 19, 16); 67990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 3, 0); 68000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 68020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = true; 68030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = true; 68040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = false; 68050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68060e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 68070e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 68080e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = Bits32 (opcode, 5, 4); 68090e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68100e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 68110e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ((t == 13) || BadReg (m)) 68120e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68130e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 68140e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68150e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingA1: 6816bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRHT; 68170e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 68180e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 15, 12); 68190e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 19, 16); 68200e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 3, 0); 68210e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6822bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 68230e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = BitIsSet (opcode, 24); 68240e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = BitIsSet (opcode, 23); 68250e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 68260e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68270e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 68280e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 68290e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = 0; 68300e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68310e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 68320e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ((t == 15) || (m == 15)) 68330e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68340e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68350e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 68360e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (wback && ((n == 15) || (n == t))) 68370e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68380e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68390e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 68400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice default: 68420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68430e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 68440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 68460e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68470e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 68480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 68490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6851a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6852a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 6853a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 68540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t offset_addr; 68560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t address; 68570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 68590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 68600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 68610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (add) 68640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = Rn + offset; 68650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else 68660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = Rn - offset; 68670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // address = if index then offset_addr else R[n]; 68690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (index) 68700e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = offset_addr; 68710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else 68720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = Rn; 68730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // data = MemU[address,2]; 6875c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 6876c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 6877c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6878c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 68790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice EmulateInstruction::Context context; 68810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextRegisterLoad; 68820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 68830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 68840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 68850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68870e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if wback then R[n] = offset_addr; 68880e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (wback) 68890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 68900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextAdjustBaseRegister; 68910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetAddress (offset_addr); 68920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 68930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 68940e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 68950e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6896bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 68970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 68980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 68990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // R[t] = ZeroExtend(data, 32); 69000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextRegisterLoad; 69010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 69020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 69030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 69040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 69050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else // Can only apply before ARMv7 69060e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 69070e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // R[t] = bits(32) UNKNOWN; 69080e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice WriteBits32Unknown (t); 69090e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 69100e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 69110e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return true; 69120e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice} 69130e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6914a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6915a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6916a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// or pre-indexed addressing. 6917a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Ticebool 69187bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6919a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice{ 6920a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#if 0 6921a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if ConditionPassed() then 6922a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6923a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6924a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = if index then offset_addr else R[n]; 6925a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 6926a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if wback then R[n] = offset_addr; 6927a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#endif 6928a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6929a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool success = false; 6930a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 69317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6932a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6933a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t t; 6934a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t n; 6935a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm32; 6936a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool index; 6937a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool add; 6938a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool wback; 6939a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6940a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6941a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice switch (encoding) 6942a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6943a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingT1: 6944bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6945bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6946a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6947a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6948a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6949a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6950a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6951a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 6952a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = true; 6953a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = true; 6954a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = false; 6955a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6956a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if t == 13 then UNPREDICTABLE; 6957a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (t == 13) 6958a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6959a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6960a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6961a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6962a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingT2: 6963bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6964bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6965bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6966bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 6967a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6968a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6969a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6970a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6971a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6972a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6973a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice imm32 = Bits32 (opcode, 7, 0); 6974a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6975bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6976a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = BitIsSet (opcode, 10); 6977a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = BitIsSet (opcode, 9); 6978a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = BitIsSet (opcode, 8); 6979a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6980a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6981bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (((t == 13) || ((t == 15) 6982bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6983bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || (wback && (n == t))) 6984a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6985a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6986a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6987a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6988a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingA1: 6989a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6990bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6991bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSBT; 6992a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6993a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6994a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6995a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6996a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 6997a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 699840b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 6999a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7000bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7001a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = BitIsSet (opcode, 24); 7002a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = BitIsSet (opcode, 23); 7003a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7004a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7005a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7006a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if ((t == 15) || (wback && (n == t))) 7007a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 7008a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7009a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 7010a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 7011a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7012a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice default: 7013a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 7014a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 7015a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7016bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice uint64_t Rn = ReadCoreReg (n, &success); 7017a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!success) 7018a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 7019a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7020a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice addr_t offset_addr; 7021a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice addr_t address; 7022a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7023a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7024a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (add) 7025a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = Rn + imm32; 7026a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice else 7027a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = Rn - imm32; 7028a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7029a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // address = if index then offset_addr else R[n]; 7030a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (index) 7031a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = offset_addr; 7032a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice else 7033a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = Rn; 7034a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7035a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 7036c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 7037c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7038a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7039a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice EmulateInstruction::Context context; 7040a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.type = eContextRegisterLoad; 7041a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 7042a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7043a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7044a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!success) 7045a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 7046a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7047a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7048a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7049a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 7050a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7051a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if wback then R[n] = offset_addr; 7052a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (wback) 7053a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 7054a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.type = eContextAdjustBaseRegister; 7055a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.SetAddress (offset_addr); 7056a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7057a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 7058a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 7059a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 7060a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 7061a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return true; 7062a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice} 70630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 70645f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 70655f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// sign-extends it to form a 32-bit word, and writes tit to a register. 70665f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Ticebool 70677bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 70685f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice{ 70695f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#if 0 70705f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if ConditionPassed() then 70715f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 70725f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice base = Align(PC,4); 70735f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = if add then (base + imm32) else (base - imm32); 70745f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 70755f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#endif 70765f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 70775f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice bool success = false; 70785f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 70797bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 70805f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 70815f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t t; 70825f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm32; 70835f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice bool add; 70845f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 70855f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 70865f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice switch (encoding) 70875f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 70885f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice case eEncodingT1: 7089bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 7090bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 70915f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice t = Bits32 (opcode, 15, 12); 70925f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice imm32 = Bits32 (opcode, 11, 0); 70935f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice add = BitIsSet (opcode, 23); 70945f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 70955f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // if t == 13 then UNPREDICTABLE; 70965f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (t == 13) 70975f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 70985f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 70995f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice break; 71005f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71015f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice case eEncodingA1: 71025f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 7103bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 71045f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice t = Bits32 (opcode, 15, 12); 71055f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 71065f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 710740b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 71085f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice add = BitIsSet (opcode, 23); 71095f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71105f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // if t == 15 then UNPREDICTABLE; 71115f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (t == 15) 71125f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 71135f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71145f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice break; 71155f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 71165f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71175f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice default: 71185f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 71195f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 71205f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71215f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // base = Align(PC,4); 71228d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 71235f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!success) 71245f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 71255f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint64_t base = AlignPC (pc_value); 71265f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71275f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // address = if add then (base + imm32) else (base - imm32); 71285f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice addr_t address; 71295f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (add) 71305f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = base + imm32; 71315f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice else 71325f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = base - imm32; 71335f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71345f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 7135c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 7136c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 71375f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71385f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice EmulateInstruction::Context context; 71395f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice context.type = eContextRegisterLoad; 71405f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 71415f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71425f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 71435f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!success) 71445f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 71455f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 71465f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 71475f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 71485f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 71495f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 71505f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return true; 71515f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice} 71525f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 7153672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7154672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7155672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// shifted left by 0, 1, 2, or 3 bits. 7156672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Ticebool 71577bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7158672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice{ 7159672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#if 0 7160672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ConditionPassed() then 7161672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7162672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 7163672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7164672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = if index then offset_addr else R[n]; 7165672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 7166672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if wback then R[n] = offset_addr; 7167672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#endif 7168672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7169672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool success = false; 7170672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 71717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7172672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 7173672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t t; 7174672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t n; 7175672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t m; 7176672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool index; 7177672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool add; 7178672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool wback; 7179672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice ARM_ShifterType shift_t; 7180672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t shift_n; 7181672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7182672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7183672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice switch (encoding) 7184672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 7185672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingT1: 7186672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7187672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 2, 0); 7188672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 5, 3); 7189672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 8, 6); 7190672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7191672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7192672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = true; 7193672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = true; 7194672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = false; 7195672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7196672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7197672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7198672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = 0; 7199672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7200672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7201672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7202672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingT2: 7203bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 7204bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 7205672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7206672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 15, 12); 7207672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 19, 16); 7208672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 3, 0); 7209672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7210672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7211672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = true; 7212672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = true; 7213672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = false; 7214672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7215672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7216672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7217672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = Bits32 (opcode, 5, 4); 7218672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7219672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 7220672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ((t == 13) || BadReg (m)) 7221672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7222672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7223672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7224672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingA1: 7225bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSBT; 7226672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7227672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 15, 12); 7228672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 19, 16); 7229672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 3, 0); 7230672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7231bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7232672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = BitIsSet (opcode, 24); 7233672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = BitIsSet (opcode, 23); 7234672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7235672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7236672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7237672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7238672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = 0; 7239672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7240672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 7241672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ((t == 15) || (m == 15)) 7242672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7243672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7244672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7245672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (wback && ((n == 15) || (n == t))) 7246672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7247672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7248672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7249672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice default: 7250672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7251672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7252672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7253672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7254672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7255672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7256672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7257672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7258a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7259a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 7260a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 7261672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7262672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t offset_addr; 7263672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t address; 7264672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7265672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7266672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7267672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7268672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7269672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7270672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (add) 7271672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = Rn + offset; 7272672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice else 7273672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = Rn - offset; 7274672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7275672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // address = if index then offset_addr else R[n]; 7276672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (index) 7277672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = offset_addr; 7278672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice else 7279672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = Rn; 7280672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7281672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 7282c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 7283c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7284c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 7285c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7286672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7287672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice EmulateInstruction::Context context; 7288672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.type = eContextRegisterLoad; 7289672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7290672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7291672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7292672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7293672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7294672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7295672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7296672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7297672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7298672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7299672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if wback then R[n] = offset_addr; 7300672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (wback) 7301672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 7302672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.type = eContextAdjustBaseRegister; 7303672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.SetAddress (offset_addr); 7304672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7305672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7306672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7307672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7308672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return true; 7309672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice} 7310672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 731178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 731278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 731378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// pre-indexed addressing. 731478fb5638da9c01a39443f3339ede2f02056822cfCaroline Ticebool 73157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 731678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice{ 731778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#if 0 731878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if ConditionPassed() then 731978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 732078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 732178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = if index then offset_addr else R[n]; 732278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice data = MemU[address,2]; 732378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if wback then R[n] = offset_addr; 7324bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 732578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice R[t] = SignExtend(data, 32); 732678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else // Can only apply before ARMv7 732778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice R[t] = bits(32) UNKNOWN; 732878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#endif 732978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 733078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool success = false; 733178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 73327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 733378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 733478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t t; 733578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t n; 733678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm32; 733778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool index; 733878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool add; 733978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool wback; 734078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 734178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 734278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice switch (encoding) 734378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 734478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingT1: 7345bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7346bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 734778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 734878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 734978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 735078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice imm32 = Bits32 (opcode, 11, 0); 735178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 735278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 735378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = true; 735478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = true; 735578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = false; 735678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 735778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if t == 13 then UNPREDICTABLE; 735878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (t == 13) 735978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 736078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 736178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 736278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 736378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingT2: 7364bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7365bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7366bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7367bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 736878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 736978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 737078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 737178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 737278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 737378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 737478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice imm32 = Bits32 (opcode, 7, 0); 737578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7376bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 737778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = BitIsSet (opcode, 10); 737878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = BitIsSet (opcode, 9); 737978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = BitIsSet (opcode, 8); 738078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 738178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 738278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (BadReg (t) || (wback && (n == t))) 738378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 738478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 738578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 738678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 738778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingA1: 738878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 7389bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7390bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSHT; 739178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 739278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 739378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 739478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm4H = Bits32 (opcode, 11,8); 739578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 739640b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 739778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7398bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 739978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = BitIsSet (opcode, 24); 740078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = BitIsSet (opcode, 23); 740178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 740278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 740378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 740478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if ((t == 15) || (wback && (n == t))) 740578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 740678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 740778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 740878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 740978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 741078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice default: 741178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 741278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 741378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 741478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 741578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 741678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!success) 741778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 741878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 741978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice addr_t offset_addr; 742078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (add) 742178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = Rn + imm32; 742278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else 742378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = Rn - imm32; 742478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 742578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // address = if index then offset_addr else R[n]; 742678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice addr_t address; 742778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (index) 742878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = offset_addr; 742978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else 743078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = Rn; 743178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 743278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // data = MemU[address,2]; 7433c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 7434c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 743578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 743678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice EmulateInstruction::Context context; 743778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextRegisterLoad; 743878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 743978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 744078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 744178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!success) 744278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 744378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 744478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if wback then R[n] = offset_addr; 744578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (wback) 744678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 744778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextAdjustBaseRegister; 744878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetAddress (offset_addr); 744978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 745078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 745178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 745278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7453bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 745478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 745578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 745678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // R[t] = SignExtend(data, 32); 745778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 745878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextRegisterLoad; 745978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 746078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 746178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 746278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 746378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else // Can only apply before ARMv7 746478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 746578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // R[t] = bits(32) UNKNOWN; 746678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice WriteBits32Unknown (t); 746778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 746878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 746978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return true; 747078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice} 747178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7472d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7473d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// sign-extends it to from a 32-bit word, and writes it to a register. 7474d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Ticebool 74757bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7476d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice{ 7477d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#if 0 7478d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if ConditionPassed() then 7479d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7480d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice base = Align(PC,4); 7481d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = if add then (base + imm32) else (base - imm32); 7482d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice data = MemU[address,2]; 7483bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 7484d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice R[t] = SignExtend(data, 32); 7485d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else // Can only apply before ARMv7 7486d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice R[t] = bits(32) UNKNOWN; 7487d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#endif 7488d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7489d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice bool success = false; 7490d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 74917bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7492d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7493d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t t; 7494d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm32; 7495d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice bool add; 7496d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7497d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7498d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice switch (encoding) 7499d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7500d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice case eEncodingT1: 7501bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 7502bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7503d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice t = Bits32 (opcode, 15, 12); 7504d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice imm32 = Bits32 (opcode, 11, 0); 7505d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice add = BitIsSet (opcode, 23); 7506d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7507d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // if t == 13 then UNPREDICTABLE; 7508d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (t == 13) 7509d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7510d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7511d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice break; 7512d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7513d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice case eEncodingA1: 7514d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7515bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7516d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice t = Bits32 (opcode, 15, 12); 7517d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 7518d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 751940b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 7520d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice add = BitIsSet (opcode, 23); 7521d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7522d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // if t == 15 then UNPREDICTABLE; 7523d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (t == 15) 7524d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7525d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7526d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice break; 7527d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7528d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice default: 7529d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7530d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7531d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7532d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // base = Align(PC,4); 75338d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7534d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!success) 7535d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7536d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7537d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint64_t base = AlignPC (pc_value); 7538d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7539d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice addr_t address; 7540d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // address = if add then (base + imm32) else (base - imm32); 7541d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (add) 7542d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = base + imm32; 7543d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else 7544d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = base - imm32; 7545d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7546d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // data = MemU[address,2]; 7547c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 7548c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7549d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7550d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice EmulateInstruction::Context context; 7551d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice context.type = eContextRegisterLoad; 7552d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice context.SetRegisterPlusOffset (base_reg, imm32); 7553d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7554d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 7555d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!success) 7556d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7557d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7558bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 7559d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 7560d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7561d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // R[t] = SignExtend(data, 32); 7562d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 7563d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7564d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7565d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7566d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else // Can only apply before ARMv7 7567d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7568d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // R[t] = bits(32) UNKNOWN; 7569d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice WriteBits32Unknown (t); 7570d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7571d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7572d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return true; 7573d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice} 7574d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7575291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7576291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7577291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// shifted left by 0, 1, 2, or 3 bits. 7578291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Ticebool 75797bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7580291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice{ 7581291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#if 0 7582291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ConditionPassed() then 7583291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7584291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 7585291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7586291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = if index then offset_addr else R[n]; 7587291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice data = MemU[address,2]; 7588291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if wback then R[n] = offset_addr; 7589bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 7590291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice R[t] = SignExtend(data, 32); 7591291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else // Can only apply before ARMv7 7592291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice R[t] = bits(32) UNKNOWN; 7593291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#endif 7594291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7595291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool success = false; 7596291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 75977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7598291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7599291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t t; 7600291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t n; 7601291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t m; 7602291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool index; 7603291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool add; 7604291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool wback; 7605291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice ARM_ShifterType shift_t; 7606291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t shift_n; 7607291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7608291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7609291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice switch (encoding) 7610291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7611291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingT1: 7612291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7613291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7614291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 2, 0); 7615291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 5, 3); 7616291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 8, 6); 7617291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7618291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7619291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = true; 7620291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = true; 7621291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = false; 7622291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7623291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7624291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7625291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = 0; 7626291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7627291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7628291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7629291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingT2: 7630bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7631bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 7632291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7633291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 15, 12); 7634291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 19, 16); 7635291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 3, 0); 7636291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7637291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7638291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = true; 7639291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = true; 7640291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = false; 7641291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7642291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7643291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7644291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = Bits32 (opcode, 5, 4); 7645291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7646291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 7647291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ((t == 13) || BadReg (m)) 7648291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7649291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7650291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7651291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7652291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingA1: 7653bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSHT; 7654291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7655291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 15, 12); 7656291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 19, 16); 7657291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 3, 0); 7658291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7659bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7660291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = BitIsSet (opcode, 24); 7661291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = BitIsSet (opcode, 23); 7662291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7663291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7664291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7665291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7666291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = 0; 7667291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7668291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 7669291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ((t == 15) || (m == 15)) 7670291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7671291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7672291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7673291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (wback && ((n == 15) || (n == t))) 7674291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7675291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7676291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7677291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7678291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice default: 76796ac9e54dfd1d3e4be4326e0f1740e6a5971c4759Johnny Chen return false; 7680291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7681291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7682291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7683291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7684291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7685291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7686291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7687291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7688291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7689291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7690291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7691a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7692a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 7693a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 7694291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7695291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t offset_addr; 7696291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t address; 7697291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7698291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7699291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (add) 7700291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = Rn + offset; 7701291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else 7702291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = Rn - offset; 7703291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7704291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // address = if index then offset_addr else R[n]; 7705291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (index) 7706291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = offset_addr; 7707291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else 7708291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = Rn; 7709291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7710291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // data = MemU[address,2]; 7711c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 7712c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7713291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7714c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 7715c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7716291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7717291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice EmulateInstruction::Context context; 7718291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextRegisterLoad; 7719291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7720291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7721291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 7722291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7723291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7724291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7725291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if wback then R[n] = offset_addr; 7726291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (wback) 7727291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7728291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextAdjustBaseRegister; 7729291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetAddress (offset_addr); 7730291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7731291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7732291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7733291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7734bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 7735291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 7736291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7737291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // R[t] = SignExtend(data, 32); 7738291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextRegisterLoad; 7739291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7740291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7741291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 7742291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7743291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7744291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7745291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else // Can only apply before ARMv7 7746291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7747291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // R[t] = bits(32) UNKNOWN; 7748291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice WriteBits32Unknown (t); 7749291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7750291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7751291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return true; 7752291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice} 77536bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77546bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 77556bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 77566bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Ticebool 77577bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 77586bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice{ 77596bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#if 0 77606bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if ConditionPassed() then 77616bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice EncodingSpecificOperations(); 77626bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotated = ROR(R[m], rotation); 77636bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice R[d] = SignExtend(rotated<7:0>, 32); 77646bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#endif 77656bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77666bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice bool success = false; 77676bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77687bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 77696bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 77706bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t d; 77716bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t m; 77726bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t rotation; 77736bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77746bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // EncodingSpecificOperations(); 77756bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice switch (encoding) 77766bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 77776bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingT1: 77786bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 77796bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 2, 0); 77806bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 5, 3); 77816bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = 0; 77826bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77836bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 77846bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77856bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingT2: 7786bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 77876bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 11, 8); 77886bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 3, 0); 77896bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 77906bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77916bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 77926bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if (BadReg (d) || BadReg (m)) 77936bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 77946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77956bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 77966bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 77976bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingA1: 7798bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 77996bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 15, 12); 78006bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 3, 0); 78016bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 78026bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78036bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 78046bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if ((d == 15) || (m == 15)) 78056bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 78066bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78076bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 78086bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78096bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice default: 78106bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 78116bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice } 78126bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 7813868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7814868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (!success) 7815868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 78166bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78176bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // rotated = ROR(R[m], rotation); 7818a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint64_t rotated = ROR (Rm, rotation, &success); 7819a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 7820a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 78216bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78226bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // R[d] = SignExtend(rotated<7:0>, 32); 78238ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice int64_t data = llvm::SignExtend64<8>(rotated); 78246bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 7825c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo source_reg; 7826c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 78276bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78286bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice EmulateInstruction::Context context; 78296bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice context.type = eContextRegisterLoad; 78306bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice context.SetRegister (source_reg); 78316bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 78328ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 78336bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 78346bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice } 78356bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return true; 78366bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice} 7837291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7838868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7839868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7840868198b229fcffbda2b24518007179ef1a45ad1dCaroline Ticebool 78417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7842868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice{ 7843868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#if 0 7844868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if ConditionPassed() then 7845868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice EncodingSpecificOperations(); 7846868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotated = ROR(R[m], rotation); 7847868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice R[d] = SignExtend(rotated<15:0>, 32); 7848868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#endif 7849868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7850868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice bool success = false; 7851868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 78527bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7853868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 7854868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t d; 7855868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t m; 7856868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t rotation; 7857868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7858868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // EncodingSpecificOperations(); 7859868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice switch (encoding) 7860868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 7861868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingT1: 7862868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7863868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 2, 0); 7864868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 5, 3); 7865868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = 0; 7866868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7867868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7868868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7869868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingT2: 7870bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7871868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 11, 8); 7872868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 3, 0); 7873868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 7874868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7875868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7876868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (BadReg (d) || BadReg (m)) 7877868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7878868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7879868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7880868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7881868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingA1: 7882bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7883868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 15, 12); 7884868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 3, 0); 7885868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 7886868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7887868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 7888868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if ((d == 15) || (m == 15)) 7889868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7890868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7891868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7892868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7893868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice default: 7894868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7895868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice } 7896868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7897868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7898868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (!success) 7899868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7900868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7901868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // rotated = ROR(R[m], rotation); 7902a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint64_t rotated = ROR (Rm, rotation, &success); 7903a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 7904a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 7905868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7906868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // R[d] = SignExtend(rotated<15:0>, 32); 7907c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo source_reg; 7908c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7909868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7910868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice EmulateInstruction::Context context; 7911868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice context.type = eContextRegisterLoad; 7912868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice context.SetRegister (source_reg); 7913868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 79148ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice int64_t data = llvm::SignExtend64<16> (rotated); 79158ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7916868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7917868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice } 7918868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7919868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return true; 7920868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice} 7921868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 79228ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 79238ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 79248ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Ticebool 79257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 79268ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice{ 79278ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#if 0 79288ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if ConditionPassed() then 79298ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice EncodingSpecificOperations(); 79308ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotated = ROR(R[m], rotation); 79318ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice R[d] = ZeroExtend(rotated<7:0>, 32); 79328ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#endif 79338ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79348ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice bool success = false; 79358ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79367bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 79378ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 79388ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t d; 79398ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t m; 79408ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t rotation; 79418ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79428ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // EncodingSpecificOperations(); 79438ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice switch (encoding) 79448ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 79458ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingT1: 79468ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 79478ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 2, 0); 79488ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 5, 3); 79498ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = 0; 79508ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79518ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 79528ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79538ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingT2: 7954bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 79558ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 11, 8); 79568ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 3, 0); 79578ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 79588ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79598ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 79608ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (BadReg (d) || BadReg (m)) 79618ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 79628ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79638ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 79648ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79658ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingA1: 7966bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 79678ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 15, 12); 79688ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 3, 0); 79698ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 79708ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79718ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 79728ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if ((d == 15) || (m == 15)) 79738ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 79748ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79758ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 79768ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79778ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice default: 79788ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 79798ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice } 79808ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79818ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 79828ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!success) 79838ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 79848ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79858ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // rotated = ROR(R[m], rotation); 7986a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint64_t rotated = ROR (Rm, rotation, &success); 7987a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 7988a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 79898ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79908ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // R[d] = ZeroExtend(rotated<7:0>, 32); 7991c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo source_reg; 7992c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 79938ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79948ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice EmulateInstruction::Context context; 79958ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice context.type = eContextRegisterLoad; 79968ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice context.SetRegister (source_reg); 79978ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 79988ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 79998ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 80008ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice } 80018ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return true; 80028ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice} 80038ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 800411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 800511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 800611555f2f0f21beb0312f8ebe40849487d437f493Caroline Ticebool 80077bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 800811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice{ 800911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#if 0 801011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if ConditionPassed() then 801111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice EncodingSpecificOperations(); 801211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotated = ROR(R[m], rotation); 801311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice R[d] = ZeroExtend(rotated<15:0>, 32); 801411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#endif 801511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 801611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice bool success = false; 801711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 80187bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 801911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 802011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t d; 802111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t m; 802211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t rotation; 802311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 802411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice switch (encoding) 802511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 802611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingT1: 802711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 802811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 2, 0); 802911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 5, 3); 803011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = 0; 803111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 803211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 803311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 803411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingT2: 8035bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 803611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 11, 8); 803711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 3, 0); 803811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 803911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 804011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 804111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (BadReg (d) || BadReg (m)) 804211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 804311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 804411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 804511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 804611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingA1: 8047bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 804811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 15, 12); 804911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 3, 0); 805011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 805111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 805211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 805311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if ((d == 15) || (m == 15)) 805411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 805511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 805611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 805711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 805811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice default: 805911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 806011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice } 806111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 806211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 806311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (!success) 806411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 806511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 806611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // rotated = ROR(R[m], rotation); 8067a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint64_t rotated = ROR (Rm, rotation, &success); 8068a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 8069a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 807011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 807111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // R[d] = ZeroExtend(rotated<15:0>, 32); 8072c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo source_reg; 8073c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 807411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 807511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice EmulateInstruction::Context context; 807611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice context.type = eContextRegisterLoad; 807711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice context.SetRegister (source_reg); 807811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 807911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 808011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 808111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice } 808211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return true; 808311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice} 8084b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8085b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8086b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// word respectively. 8087b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 80887bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8089b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 8090b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#if 0 8091b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if ConditionPassed() then 8092b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice EncodingSpecificOperations(); 8093b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8094b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice UNPREDICTABLE; 8095b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 8096b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = if increment then R[n] else R[n]-8; 8097b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if wordhigher then address = address+4; 8098bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8099b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice BranchWritePC(MemA[address,4]); 8100b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8101b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#endif 8102b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8103b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool success = false; 8104b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 81057bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 8106b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8107b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint32_t n; 8108b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool wback; 8109b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool increment; 8110b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool wordhigher; 8111b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8112b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // EncodingSpecificOperations(); 8113b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice switch (encoding) 8114b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8115b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingT1: 8116bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8117b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 8118b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 8119b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = false; 8120b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = false; 8121b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8122b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 8123b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 8124b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8125b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8126b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8127b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (InITBlock() && !LastInITBlock()) 8128b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8129b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8130b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 8131b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8132b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingT2: 8133bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8134b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 8135b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 8136b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = true; 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 eEncodingA1: 8150b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // n = UInt(Rn); 8151b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 8152b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8153bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8154b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 8155b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = BitIsSet (opcode, 23); 8156b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8157b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8158b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 8159b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 8160b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8161b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8162b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 8163b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8164b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice default: 8165b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8166b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8167b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8168b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8169b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!CurrentModeIsPrivileged ()) 8170b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // UNPREDICTABLE; 8171b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8172b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 8173b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8174b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8175b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 8176b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8177b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8178b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice addr_t address; 8179b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // address = if increment then R[n] else R[n]-8; 8180b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (increment) 8181b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = Rn; 8182b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 8183b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = Rn - 8; 8184b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8185b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if wordhigher then address = address+4; 8186b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (wordhigher) 8187b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = address + 4; 8188b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8189bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8190c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 8191c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8192b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8193b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice EmulateInstruction::Context context; 8194b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.type = eContextReturnFromException; 8195b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 8196b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8197b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8198b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 8199b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8200b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8201b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice CPSRWriteByInstr (data, 15, true); 8202b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8203b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // BranchWritePC(MemA[address,4]); 8204b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t data2 = MemARead (context, address, 4, 0, &success); 8205b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 8206b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8207b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8208b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice BranchWritePC (context, data2); 8209b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 8210b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8211b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (wback) 8212b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8213b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.type = eContextAdjustBaseRegister; 8214b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (increment) 8215b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8216b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetOffset (8); 8217b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8218b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8219b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8220b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 8221b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8222b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetOffset (-8); 8223b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8224b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8225b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8226b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } // if wback 8227b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8228b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } // if ConditionPassed() 8229b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 8230b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 823111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 82322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 82332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags based on 82342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 82352115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 82367bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 82372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 82382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 82392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 82402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 82412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 82422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 82432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 82442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 82452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 82462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 82472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 82482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 82492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 82502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 82512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 82522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 82532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 82542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 82552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 82567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 82572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 82582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn; 82592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 82602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 82612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 82622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 82632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 82642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 82652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 82662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 82672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 82682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 82692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 82702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 82717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTEQImm (opcode, eEncodingT1); 82722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 82732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 82742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 82752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 82762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 82772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 82782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 82792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 82801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 82812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 82822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 82831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 82842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 82852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 82862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 82872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 82882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 82892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 82902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 82912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 82922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 82932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 82942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 82952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 82962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 82972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 82982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 82992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 83012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 83022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 83032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 83042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 83052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 83072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value, and writes the result to the destination register. 83082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// It can optionally update the condition flags based on the result. 83092115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 83107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 83112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 83122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 83132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 83142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 83152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 83162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 83172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 83182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 83192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 83202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 83212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 83222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 83232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 83242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 83252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 83262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 83272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 83282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 83302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 83322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 83332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn, Rm; 83342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 83352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 83362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 83372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 83382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 83392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 83402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 83412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 83422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 5, 3); 83432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = !InITBlock(); 83442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_t = SRType_LSL; 83452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = 0; 8346ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 83472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT2: 83482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 83492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 83502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 83512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 83523dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 83533dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (register); 83542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 83557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTEQReg (opcode, eEncodingT1); 83562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 83572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 83582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 83592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 83602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 83612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 83622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 83632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 83643dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 83651f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 83662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 83672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 83681f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 83692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 83702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 83712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 83722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 83732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 83752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 83762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 83772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 83782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 83802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 83812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 83822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 83832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 8384a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8385a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 8386a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 83872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 83882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 83902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 83912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 83922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 83942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 83952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 83962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 83972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 83982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 83997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 84007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// writes the result to the destination register. It can optionally update the condition flags based 84017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 84027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 84037bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 84047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 84057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 84067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 84077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 84087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 84097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR imm32; 84107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 84117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 84127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 84137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 84147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 84157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 84167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 84177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 84187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 84197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 84207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 84227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 84247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 84257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn; 84267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 84277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 84287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 84297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 84307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 84317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 84327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 84337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 84347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 84357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8436bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE MOV (immediate); 84377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 84387bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdImm (opcode, eEncodingT2); 84397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13) 84407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 84417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 84427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 84437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 84447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 84457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 84467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 84471f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 84487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 84491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 84507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 84517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 84527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 84537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 84547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 84567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 84577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 84587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 84597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = val1 | imm32; 84617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 84637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 84647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 84657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84667c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 84677c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 84687c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 84697c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 84707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 84717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 84737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// value, and writes the result to the destination register. It can optionally update the condition flags based 84747c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 84757c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 84767bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 84777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 84787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 84797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 84807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 84817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 84827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 84837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR shifted; 84847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 84857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 84867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 84877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 84887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 84897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 84907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 84917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 84927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 84937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 84947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 84967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 84977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 84987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 84997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn, Rm; 85007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ARM_ShifterType shift_t; 85017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 85027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 85037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; 85047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 85057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 85067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 85077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 85087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 5, 3); 85097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = !InITBlock(); 85107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_t = SRType_LSL; 85117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_n = 0; 8512ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 85137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT2: 85147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 85157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 85167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 85177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 85183dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 85193dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen // if Rn == '1111' then SEE MOV (register); 85207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 85217bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdRm (opcode, eEncodingT3); 85227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 85237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 85247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 85257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 85267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 85277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 85287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 85297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 85303dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 85311f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 85327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 85331f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 85347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 85357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 85367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 85377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 85387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 85397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 85407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 85417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 85427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 85437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 85447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the second operand. 85457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 85467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 85477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 85487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 8549a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8550a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 8551a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 85522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 | shifted; 85537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 85547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 85557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 85567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 85577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 85587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 85597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 85607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 85617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 85627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 85637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 8564ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8565ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// the destination register. It can optionally update the condition flags based on the result. 8566ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool 85677bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8568ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{ 8569ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0 8570ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // ARM pseudo code... 8571ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if ConditionPassed() then 8572ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EncodingSpecificOperations(); 8573ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8574ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if d == 15 then // Can only occur for ARM encoding 8575ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ALUWritePC(result); // setflags is always FALSE here 8576ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen else 8577ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen R[d] = result; 8578ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if setflags then 8579ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.N = result<31>; 8580ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.Z = IsZeroBit(result); 8581ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.C = carry; 8582ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.V = overflow; 8583ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif 8584ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8585ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool success = false; 8586ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8587ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rd; // the destination register 8588ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rn; // the first operand 8589ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool setflags; 8590ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8591ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen switch (encoding) { 8592ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT1: 8593ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 2, 0); 8594ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 5, 3); 8595ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = !InITBlock(); 8596ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = 0; 8597ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8598ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT2: 8599ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 11, 8); 8600ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8601ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8602ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8603ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 8604ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8605ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8606ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingA1: 8607ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 15, 12); 8608ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8609ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8610ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 86111f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 8612ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8613ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (Rd == 15 && setflags) 86141f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 8615ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8616ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen default: 8617ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8618ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen } 8619ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from the operand register Rn. 8620ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 8621ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8622ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8623ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8624ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8625ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8626ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EmulateInstruction::Context context; 8627ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.type = EmulateInstruction::eContextImmediate; 8628ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.SetNoArgs (); 8629ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8630ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8631ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8632ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8633ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return true; 8634ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen} 8635ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8636ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8637ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// result to the destination register. It can optionally update the condition flags based on the result. 8638ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool 86397bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8640ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{ 8641ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0 8642ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // ARM pseudo code... 8643ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if ConditionPassed() then 8644ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EncodingSpecificOperations(); 8645ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8646ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8647ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if d == 15 then // Can only occur for ARM encoding 8648ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ALUWritePC(result); // setflags is always FALSE here 8649ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen else 8650ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen R[d] = result; 8651ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if setflags then 8652ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.N = result<31>; 8653ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.Z = IsZeroBit(result); 8654ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.C = carry; 8655ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.V = overflow; 8656ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif 8657ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8658ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool success = false; 8659ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8660ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rd; // the destination register 8661ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rn; // the first operand 8662ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rm; // the second operand 8663ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool setflags; 8664ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ARM_ShifterType shift_t; 8665ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 8666ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen switch (encoding) { 8667ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT1: 8668ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 11, 8); 8669ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8670ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rm = Bits32(opcode, 3, 0); 8671ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8672ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 8673ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8674ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8675ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8676ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8677ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingA1: 8678ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 15, 12); 8679ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8680ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rm = Bits32(opcode, 3, 0); 8681ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8682ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 86831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 8684ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8685ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (Rd == 15 && setflags) 86861f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 8687ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8688ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen default: 8689ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8690ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen } 8691ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from register Rn. 8692ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 8693ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8694ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8695ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8696ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from register Rm. 8697ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 8698ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8699ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8700ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8701a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8702a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 8703a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 8704ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8705ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8706ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EmulateInstruction::Context context; 8707ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.type = EmulateInstruction::eContextImmediate; 8708ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.SetNoArgs(); 8709ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8710ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8711ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8712ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return true; 8713ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen} 8714ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 871590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 871690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// an immediate value, and writes the result to the destination register. It can optionally update the condition 871790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// flags based on the result. 871890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool 87197bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 872090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{ 872190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0 872290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // ARM pseudo code... 872390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if ConditionPassed() then 872490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EncodingSpecificOperations(); 872590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 872690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if d == 15 then 872790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ALUWritePC(result); // setflags is always FALSE here 872890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen else 872990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen R[d] = result; 873090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if setflags then 873190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.N = result<31>; 873290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.Z = IsZeroBit(result); 873390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.C = carry; 873490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.V = overflow; 873590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif 873690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 873790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool success = false; 873890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 873990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rd; // the destination register 874090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rn; // the first operand 874190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool setflags; 874290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 874390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen switch (encoding) { 874490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen case eEncodingA1: 874590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rd = Bits32(opcode, 15, 12); 874690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rn = Bits32(opcode, 19, 16); 874790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen setflags = BitIsSet(opcode, 20); 874890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 87491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 875090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 875190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (Rd == 15 && setflags) 87521f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 875390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen break; 875490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen default: 875590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 875690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen } 875790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from the operand register Rn. 875890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 875990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 876090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 876190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 876290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 876390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 876490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EmulateInstruction::Context context; 876590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.type = EmulateInstruction::eContextImmediate; 876690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.SetNoArgs (); 876790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 876890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 876990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 877090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 877190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return true; 877290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen} 877390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 877490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 877590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 877690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// condition flags based on the result. 877790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool 87787bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 877990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{ 878090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0 878190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // ARM pseudo code... 878290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if ConditionPassed() then 878390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EncodingSpecificOperations(); 878490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 878590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 878690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if d == 15 then 878790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ALUWritePC(result); // setflags is always FALSE here 878890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen else 878990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen R[d] = result; 879090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if setflags then 879190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.N = result<31>; 879290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.Z = IsZeroBit(result); 879390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.C = carry; 879490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.V = overflow; 879590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif 879690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 879790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool success = false; 879890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 879990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rd; // the destination register 880090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rn; // the first operand 880190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rm; // the second operand 880290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool setflags; 880390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ARM_ShifterType shift_t; 880490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 880590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen switch (encoding) { 880690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen case eEncodingA1: 880790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rd = Bits32(opcode, 15, 12); 880890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rn = Bits32(opcode, 19, 16); 880990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rm = Bits32(opcode, 3, 0); 881090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen setflags = BitIsSet(opcode, 20); 881190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 88121f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 881390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 881490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (Rd == 15 && setflags) 88151f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 881690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen break; 881790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen default: 881890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 881990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen } 882090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from register Rn. 882190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 882290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 882390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 882490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 882590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from register Rm. 882690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 882790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 882890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 882990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 8830a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8831a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 8832a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 883390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 883490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 883590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EmulateInstruction::Context context; 883690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.type = EmulateInstruction::eContextImmediate; 883790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.SetNoArgs(); 883890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 883990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 884090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 884190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return true; 884290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen} 884390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 88449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (immediate) subtracts an immediate value and the value of 88459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register. 88469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result. 88479b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool 88487bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 88499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{ 88509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0 88519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // ARM pseudo code... 88529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if ConditionPassed() then 88539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EncodingSpecificOperations(); 885415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 88559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if d == 15 then // Can only occur for ARM encoding 88569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 88579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen else 88589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen R[d] = result; 88599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if setflags then 88609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.N = result<31>; 88619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.Z = IsZeroBit(result); 88629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.C = carry; 88639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.V = overflow; 88649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif 88659b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 88669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool success = false; 88679b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 88689b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rd; // the destination register 88699b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rn; // the first operand 88709b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool setflags; 88719b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 88729b381775c532270fd07a90aa1a98750546a768b7Johnny Chen switch (encoding) { 88739b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT1: 88749b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 11, 8); 88759b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 88769b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 88779b381775c532270fd07a90aa1a98750546a768b7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 88789b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 88799b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 88809b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 88819b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingA1: 88829b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 15, 12); 88839b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 88849b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 88859b381775c532270fd07a90aa1a98750546a768b7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 88861f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 88879b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 88889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (Rd == 15 && setflags) 88891f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 88909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 88919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen default: 88929b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 88939b381775c532270fd07a90aa1a98750546a768b7Johnny Chen } 88949b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from the operand register Rn. 88959b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 88969b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 88979b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 88989b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 88999b381775c532270fd07a90aa1a98750546a768b7Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 89009b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89019b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EmulateInstruction::Context context; 89029b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 89039b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.SetNoArgs (); 89049b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89059b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 89069b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 89079b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89089b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return true; 89099b381775c532270fd07a90aa1a98750546a768b7Johnny Chen} 89109b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89119b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 89129b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register. 89139b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result. 89149b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool 89157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 89169b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{ 89179b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0 89189b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // ARM pseudo code... 89199b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if ConditionPassed() then 89209b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EncodingSpecificOperations(); 89219b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 89229b381775c532270fd07a90aa1a98750546a768b7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 89239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if d == 15 then // Can only occur for ARM encoding 89249b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 89259b381775c532270fd07a90aa1a98750546a768b7Johnny Chen else 89269b381775c532270fd07a90aa1a98750546a768b7Johnny Chen R[d] = result; 89279b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if setflags then 89289b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.N = result<31>; 89299b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.Z = IsZeroBit(result); 89309b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.C = carry; 89319b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.V = overflow; 89329b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif 89339b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89349b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool success = false; 89359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89369b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rd; // the destination register 89379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rn; // the first operand 89389b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rm; // the second operand 89399b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool setflags; 89409b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ARM_ShifterType shift_t; 89419b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 89429b381775c532270fd07a90aa1a98750546a768b7Johnny Chen switch (encoding) { 89439b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT1: 89449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 89459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 5, 3); 89469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = !InITBlock(); 89479b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_t = SRType_LSL; 89489b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = 0; 89499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 89509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT2: 89519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 11, 8); 89529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 89539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 3, 0); 89549b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 89559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 89569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 89579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 89589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 89599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingA1: 89609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 15, 12); 89619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 89629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 3, 0); 89639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 89649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 89651f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 89669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 89679b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (Rd == 15 && setflags) 89681f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 89699b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 89709b381775c532270fd07a90aa1a98750546a768b7Johnny Chen default: 89719b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 89729b381775c532270fd07a90aa1a98750546a768b7Johnny Chen } 89739b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from register Rn. 89749b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 89759b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 89769b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 89779b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89789b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from register Rm. 89799b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 89809b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 89819b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 89829b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 8983a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8984a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 8985a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 89869b381775c532270fd07a90aa1a98750546a768b7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 89879b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EmulateInstruction::Context context; 89899b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 89909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.SetNoArgs(); 89919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 89929b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 89939b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 89949b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return true; 89959b381775c532270fd07a90aa1a98750546a768b7Johnny Chen} 89969b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 899715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result 899815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register. It can optionally update the condition flags based on the result. 899915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool 90007bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 900115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{ 900215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0 900315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // ARM pseudo code... 900415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if ConditionPassed() then 900515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EncodingSpecificOperations(); 900615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 900715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen R[d] = result; 900815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if setflags then 900915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.N = result<31>; 901015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.Z = IsZeroBit(result); 901115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.C = carry; 901215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.V = overflow; 901315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif 901415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 901515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool success = false; 901615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 901715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rd; // the destination register 901815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rn; // the first operand 901915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool setflags; 902015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 902115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen switch (encoding) { 902215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT1: 902315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 2, 0); 902415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 5, 3); 902515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = !InITBlock(); 902615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 902715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 902815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT2: 902915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Rn = Bits32(opcode, 10, 8); 903015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = !InITBlock(); 903115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 903215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 903315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT3: 903415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 11, 8); 903515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 903615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 903715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 903815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 903915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE CMP (immediate); 904015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 90417bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateCMPImm (opcode, eEncodingT2); 904215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 9043bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE SUB (SP minus immediate); 904415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 90457bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingT2); 904615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 904715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 904815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 904915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 905015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 905115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT4: 905215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 11, 8); 905315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 905415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 905515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 905615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 905715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rn == '1111' then SEE ADR; 905815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 15) 90597bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateADR (opcode, eEncodingT2); 906015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 906115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rn == '1101' then SEE SUB (SP minus immediate); 906215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 90637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingT3); 906415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 906515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (BadReg(Rd)) 906615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 906715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 906815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen default: 906915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 907015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen } 907115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // Read the register value from the operand register Rn. 907215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 907315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!success) 907415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 907515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 907615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 907715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 907815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EmulateInstruction::Context context; 907915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.type = EmulateInstruction::eContextImmediate; 908015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.SetNoArgs (); 908115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 908215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 908315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 908415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 908515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return true; 908615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen} 908715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 908815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result 908915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register. It can optionally update the condition flags based on the result. 909015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool 90917bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 909215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{ 909315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0 909415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // ARM pseudo code... 909515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if ConditionPassed() then 909615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EncodingSpecificOperations(); 909715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 909815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if d == 15 then 909915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen ALUWritePC(result); // setflags is always FALSE here 910015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen else 910115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen R[d] = result; 910215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if setflags then 910315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.N = result<31>; 910415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.Z = IsZeroBit(result); 910515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.C = carry; 910615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.V = overflow; 910715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif 910815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 910915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool success = false; 911015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 911115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rd; // the destination register 911215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rn; // the first operand 911315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool setflags; 911415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 911515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen switch (encoding) { 911615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingA1: 911715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 15, 12); 911815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 911915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 912015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 912115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 9122bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' && S == '0' then SEE ADR; 912315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 15 && !setflags) 91247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateADR (opcode, eEncodingA2); 912515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 9126bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE SUB (SP minus immediate); 912715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 91287bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingA1); 912915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 913015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 913115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 91321f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return EmulateSUBSPcLrEtc (opcode, encoding); 913315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 913415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen default: 913515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 913615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen } 913715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // Read the register value from the operand register Rn. 913815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 913915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!success) 914015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 914115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 914215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 914315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 914415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EmulateInstruction::Context context; 914515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.type = EmulateInstruction::eContextImmediate; 914615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.SetNoArgs (); 914715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 914815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 914915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 915015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 915115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return true; 915215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen} 915315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 91542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 91552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// immediate value. It updates the condition flags based on the result, and discards the result. 91562115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 91577bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 91582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 91592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 91602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 91612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 91622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 91632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 91642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 91652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 91662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 91672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 91682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 91692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 91702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 91712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 91727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 91732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 91742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn; 91752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 91762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 91772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 91782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 91792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 91802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 91817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 91822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn)) 91832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 91842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 91852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 91862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 91877bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 91882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 91892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 91902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 91912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 91922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 91932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 91942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 91952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 91962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 91972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 91982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 91992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 92012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 92022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 92032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 92052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 92062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 92072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 92082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 92092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 92112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value. It updates the condition flags based on the result, and discards 92122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 92132115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 92147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 92152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 92162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 92172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 92182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 92192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 92202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 92212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 92222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 92232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 92242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 92252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 92262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 92272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 92292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92307bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 92312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 92322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn, Rm; 92332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 92342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 92352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 92362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 92372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 92382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 92392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 92402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 92413dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 92422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn) || BadReg(Rm)) 92432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 92442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 92452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 92462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 92472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 92483dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 92492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 92502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 92512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 92522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 92532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 92552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 92562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 92572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 92582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 92602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 92612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 92622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 92632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 9264a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9265a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 9266a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 92672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 92682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 92702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 92712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 92722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 92732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 92742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 92752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 92762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 92772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 92782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 9279de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9280de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 9281de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 92827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9283de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 9284de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 9285de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 9286de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 9287de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 9288de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND imm32; 9289de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 9290de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 9291de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 9292de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 9293de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 9294de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9295de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 9296de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 92977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9298de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9299de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn; 9300de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9301de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9302de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 9303de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9304de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 9305de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9306de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9307de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn)) 9308de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9309de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9310de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 9311de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9312de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9313de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9314de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 9315de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9316de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9317de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9318de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 9319de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 9320de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9321de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9322de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9323de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & imm32; 9324de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9325de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 9326de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 9327de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 9328de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9329de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 9330de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9331de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9332de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 9333de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 9334de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9335de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9336de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 9337de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 93387bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9339de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 9340de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 9341de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 9342de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 9343de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 9344de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9345de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND shifted; 9346de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 9347de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 9348de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 9349de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 9350de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 9351de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9352de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 9353de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 93547bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9355de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9356de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn, Rm; 9357de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen ARM_ShifterType shift_t; 9358de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 9359de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; 9360de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 9361de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9362de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 9363de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 2, 0); 9364de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 5, 3); 9365de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_t = SRType_LSL; 9366de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_n = 0; 9367ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 9368de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT2: 9369de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9370de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 93713dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 9372de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn) || BadReg(Rm)) 9373de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9374de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9375de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 9376de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9377de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 93783dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 9379de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9380de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 9381de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9382de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9383de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9384de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 9385de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 9386de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9387de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9388de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9389de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the second operand. 9390de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 9391de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9392de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9393de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9394a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9395a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 9396a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 9397de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & shifted; 9398de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9399de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 9400de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 9401de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 9402de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9403de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 9404de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9405de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9406de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 9407de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 9408d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9409d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.216 SUB (SP minus register) 9410d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9411d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9412d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9413d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9414d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ConditionPassed() then 9415d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice EncodingSpecificOperations(); 9416d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9417061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9418d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if d == 15 then // Can only occur for ARM encoding 9419d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice ALUWritePC(result); // setflags is always FALSE here 9420d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice else 9421d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice R[d] = result; 9422d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if setflags then 9423d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.N = result<31>; 9424d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.Z = IsZeroBit(result); 9425d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.C = carry; 9426d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.V = overflow; 9427d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9428d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9429d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice bool success = false; 9430d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9431d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9432d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9433d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t d; 9434d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t m; 9435d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice bool setflags; 9436d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice ARM_ShifterType shift_t; 9437d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t shift_n; 9438d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9439d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9440d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9441d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice case eEncodingT1: 9442061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9443d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice d = Bits32 (opcode, 11, 8); 9444d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice m = Bits32 (opcode, 3, 0); 9445d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice setflags = BitIsSet (opcode, 20); 9446d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9447d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9448d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shift_n = DecodeImmShiftThumb (opcode, shift_t); 9449d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9450d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9451d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9452d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9453d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9454d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if d == 15 || BadReg(m) then UNPREDICTABLE; 9455d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ((d == 15) || BadReg (m)) 9456d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9457d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice break; 9458d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9459d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice case eEncodingA1: 9460061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9461d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice d = Bits32 (opcode, 15, 12); 9462d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice m = Bits32 (opcode, 3, 0); 9463d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice setflags = BitIsSet (opcode, 20); 94641f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 9465061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 94661f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (d == 15 && setflags) 94671f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice EmulateSUBSPcLrEtc (opcode, encoding); 9468d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9469d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9470d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shift_n = DecodeImmShiftARM (opcode, shift_t); 9471d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice break; 9472d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9473d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice default: 9474d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9475d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9476d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9477d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9478d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 9479d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!success) 9480d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9481d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9482a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9483a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 9484a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 9485d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9486061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9487d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9488d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!success) 9489d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9490d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9491d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9492d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9493d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice EmulateInstruction::Context context; 9494c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 9495c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo sp_reg; 9496c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9497c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo dwarf_reg; 9498c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9499d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9500d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9501ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9502d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9503d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9504d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9505d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9506d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9507d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9508d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.7 ADD (register-shifted register) 9509d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9510c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline TiceEmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9511d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9512d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9513c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if ConditionPassed() then 9514c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice EncodingSpecificOperations(); 9515c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice shift_n = UInt(R[s]<7:0>); 9516c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9517061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9518c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice R[d] = result; 9519c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if setflags then 9520c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.N = result<31>; 9521c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.Z = IsZeroBit(result); 9522c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.C = carry; 9523c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.V = overflow; 9524d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9525d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9526c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice bool success = false; 9527d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9528d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9529d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9530c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t d; 9531c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t n; 9532c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t m; 9533c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t s; 9534c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice bool setflags; 9535c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice ARM_ShifterType shift_t; 9536c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9537d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9538d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9539c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice case eEncodingA1: 9540c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9541c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice d = Bits32 (opcode, 15, 12); 9542c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice n = Bits32 (opcode, 19, 16); 9543c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice m = Bits32 (opcode, 3, 0); 9544c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice s = Bits32 (opcode, 11, 8); 9545c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9546061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9547c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice setflags = BitIsSet (opcode, 20); 9548c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9549c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9550c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9551c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9552c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9553c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice break; 9554c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9555c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice default: 9556c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9557d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9558c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9559c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // shift_n = UInt(R[s]<7:0>); 9560c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t Rs = ReadCoreReg (s, &success); 9561c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!success) 9562c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9563c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9564c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t shift_n = Bits32 (Rs, 7, 0); 9565c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9566c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9567c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t Rm = ReadCoreReg (m, &success); 9568c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!success) 9569c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9570c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9571a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9572a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 9573a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 9574a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen 9575061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9576c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 9577c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!success) 9578c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9579c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9580c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9581c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9582c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // R[d] = result; 9583c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice EmulateInstruction::Context context; 9584c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 9585c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo reg_n; 9586c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9587c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo reg_m; 9588c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9589c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9590c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice context.SetRegisterRegisterOperands (reg_n, reg_m); 9591c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9592c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9593c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9594c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9595c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // if setflags then 9596c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.N = result<31>; 9597c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.Z = IsZeroBit(result); 9598c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.C = carry; 9599c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.V = overflow; 9600c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (setflags) 9601c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return WriteFlags (context, res.result, res.carry_out, res.overflow); 9602d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9603d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9604d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9605d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9606d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.213 SUB (register) 9607d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9608d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9609d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9610d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 96114cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if ConditionPassed() then 96124cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice EncodingSpecificOperations(); 96134cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9614061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 96154cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if d == 15 then // Can only occur for ARM encoding 96164cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice ALUWritePC(result); // setflags is always FALSE here 96174cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice else 96184cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice R[d] = result; 96194cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if setflags then 96204cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.N = result<31>; 96214cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.Z = IsZeroBit(result); 96224cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.C = carry; 96234cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.V = overflow; 9624d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9625d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 96264cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice bool success = false; 9627d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9628d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9629d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 96304cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t d; 96314cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t n; 96324cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t m; 96334cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice bool setflags; 96344cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice ARM_ShifterType shift_t; 96354cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t shift_n; 96364cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9637d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9638d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 96394cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice case eEncodingT1: 96404cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 96414cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice d = Bits32 (opcode, 2, 0); 96424cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice n = Bits32 (opcode, 5, 3); 96434cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice m = Bits32 (opcode, 8, 6); 96444cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice setflags = !InITBlock(); 96454cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96464cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 96474cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_t = SRType_LSL; 96484cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_n = 0; 96494cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96504cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice break; 96514cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96524cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice case eEncodingT2: 9653061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rd == �1111� && S == �1� then SEE CMP (register); 9654061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rn == �1101� then SEE SUB (SP minus register); 9655061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 96564cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice d = Bits32 (opcode, 11, 8); 96574cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice n = Bits32 (opcode, 19, 16); 96584cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice m = Bits32 (opcode, 3, 0); 96594cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice setflags = BitIsSet (opcode, 20); 96604cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96614cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 96624cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_n = DecodeImmShiftThumb (opcode, shift_t); 96634cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96644cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 96654cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 96664cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 96674cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96684cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice break; 96694cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96704cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice case eEncodingA1: 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, 15, 12); 96744cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice n = Bits32 (opcode, 19, 16); 96754cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice m = Bits32 (opcode, 3, 0); 96764cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice setflags = BitIsSet (opcode, 20); 96771f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 9678061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 96791f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if ((d == 15) && setflags) 96801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice EmulateSUBSPcLrEtc (opcode, encoding); 96814cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96824cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 96834cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_n = DecodeImmShiftARM (opcode, shift_t); 96844cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96854cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice break; 96864cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96874cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice default: 96884cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 9689d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 96904cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 96914cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 96924cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 96934cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if (!success) 96944cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 96954cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9696a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9697a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 9698a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 96994cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9700061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 97014cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 97024cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if (!success) 97034cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 97044cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 97054cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 97064cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 97074cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if d == 15 then // Can only occur for ARM encoding 97084cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // ALUWritePC(result); // setflags is always FALSE here 97094cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // else 97104cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // R[d] = result; 97114cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if setflags then 97124cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.N = result<31>; 97134cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.Z = IsZeroBit(result); 97144cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.C = carry; 97154cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.V = overflow; 97164cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 97174cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice EmulateInstruction::Context context; 9718c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.type = eContextArithmetic; 9719c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo reg_n; 9720c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9721c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo reg_m; 9722c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 97234cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice context.SetRegisterRegisterOperands (reg_n, reg_m); 97244cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9725ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 97264cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 9727d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9728d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9729d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 97304cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9731d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.202 STREX 97325168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 97335168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice// word from a register to memory if the executing processor has exclusive access to the memory addressed. 9734d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9735d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9736d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9737d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 97385168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ConditionPassed() then 97395168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 97405168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice address = R[n] + imm32; 97415168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ExclusiveMonitorsPass(address,4) then 97425168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice MemA[address,4] = R[t]; 97435168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice R[d] = 0; 97445168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice else 97455168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice R[d] = 1; 9746d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9747d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 97485168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice bool success = false; 9749d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9750d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9751d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 97525168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t d; 97535168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t t; 97545168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t n; 97555168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t imm32; 97565168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 97575168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 9758d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9759d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 97605168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice case eEncodingT1: 9761061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 97625168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice d = Bits32 (opcode, 11, 8); 97635168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice t = Bits32 (opcode, 15, 12); 97645168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice n = Bits32 (opcode, 19, 16); 97655168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 97665168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 97675168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 97685168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (BadReg (d) || BadReg (t) || (n == 15)) 97695168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 97705168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 97715168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if d == n || d == t then UNPREDICTABLE; 97725168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ((d == n) || (d == t)) 97735168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 97745168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 97755168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice break; 97765168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 97775168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice case eEncodingA1: 97785168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 97795168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice d = Bits32 (opcode, 15, 12); 97805168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice t = Bits32 (opcode, 3, 0); 97815168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice n = Bits32 (opcode, 19, 16); 97825168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice imm32 = 0; 97835168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 97845168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 97855168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ((d == 15) || (t == 15) || (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 default: 97955168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 97965168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice } 97975168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 97985168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // address = R[n] + imm32; 97995168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 98005168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!success) 98015168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 98025168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 98035168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice addr_t address = Rn + imm32; 98045168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 9805c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 9806c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9807c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 9808c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 98095168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice EmulateInstruction::Context context; 98105168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice context.type = eContextRegisterStore; 98115168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 98125168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 98135168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if ExclusiveMonitorsPass(address,4) then 98145168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 98155168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // always return true. 98165168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (true) 98175168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice { 98185168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // MemA[address,4] = R[t]; 98195168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 98205168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!success) 98215168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 98225168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 98235168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!MemAWrite (context, address, Rt, addr_byte_size)) 98245168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 98255168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 98265168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // R[d] = 0; 98275168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 98285168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 98295168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice } 98305168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice else 98315168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice { 98325168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // R[d] = 1; 98335168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 98345168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 9835d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9836d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9837d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9838d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9839d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9840d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.197 STRB (immediate, ARM) 9841d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9842d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9843d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9844d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9845ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if ConditionPassed() then 9846ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice EncodingSpecificOperations(); 9847ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9848ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice address = if index then offset_addr else R[n]; 9849ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice MemU[address,1] = R[t]<7:0>; 9850ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if wback then R[n] = offset_addr; 9851d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9852d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9853ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool success = false; 9854d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9855d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9856d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9857ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t t; 9858ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t n; 9859ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t imm32; 9860ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool index; 9861ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool add; 9862ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool wback; 9863ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9864d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9865d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9866ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice case eEncodingA1: 9867061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && W == �1� then SEE STRBT; 9868ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9869ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice t = Bits32 (opcode, 15, 12); 9870ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice n = Bits32 (opcode, 19, 16); 9871ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice imm32 = Bits32 (opcode, 11, 0); 9872ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9873061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9874ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice index = BitIsSet (opcode, 24); 9875ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice add = BitIsSet (opcode, 23); 9876ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9877ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9878ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if t == 15 then UNPREDICTABLE; 9879ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (t == 15) 9880ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9881ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9882ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9883ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (wback && ((n == 15) || (n == t))) 9884ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9885ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9886ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice break; 9887ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9888ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice default: 9889ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9890ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice } 9891ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9892ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9893ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 9894ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!success) 9895ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9896ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9897ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice addr_t offset_addr; 9898ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (add) 9899ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice offset_addr = Rn + imm32; 9900ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice else 9901ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice offset_addr = Rn - imm32; 9902ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9903ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // address = if index then offset_addr else R[n]; 9904ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice addr_t address; 9905ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (index) 9906ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice address = offset_addr; 9907ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice else 9908ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice address = Rn; 9909ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9910ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // MemU[address,1] = R[t]<7:0>; 9911ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t Rt = ReadCoreReg (t, &success); 9912ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!success) 9913ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9914ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9915c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 9916c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9917c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 9918c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9919ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice EmulateInstruction::Context context; 9920ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice context.type = eContextRegisterStore; 9921ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9922ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9923ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9924ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9925ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9926ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if wback then R[n] = offset_addr; 9927ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (wback) 9928ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice { 9929523c554292bc09fd8519379d628b5e9090acbd36Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9930ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9931d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9932d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9933d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9934d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9935d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9936d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.194 STR (immediate, ARM) 9937d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9938d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9939d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9940d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9941d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if ConditionPassed() then 9942d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice EncodingSpecificOperations(); 9943d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9944d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice address = if index then offset_addr else R[n]; 9945d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9946d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if wback then R[n] = offset_addr; 9947d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9948d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9949d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool success = false; 9950d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9951d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9952d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9953d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t t; 9954d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t n; 9955d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t imm32; 9956d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool index; 9957d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool add; 9958d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool wback; 9959d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9960d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 9961d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9962d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9963d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9964d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice case eEncodingA1: 9965061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && W == �1� then SEE STRT; 9966061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9967d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9968d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice t = Bits32 (opcode, 15, 12); 9969d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice n = Bits32 (opcode, 19, 16); 9970d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice imm32 = Bits32 (opcode, 11, 0); 9971d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9972061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9973d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice index = BitIsSet (opcode, 24); 9974d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice add = BitIsSet (opcode, 23); 9975d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9976d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9977d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9978d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (wback && ((n == 15) || (n == t))) 9979d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9980d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9981d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice break; 9982d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9983d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice default: 9984d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9985d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice } 9986d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9987d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9988d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 9989d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!success) 9990d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9991d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9992d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice addr_t offset_addr; 9993d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (add) 9994d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice offset_addr = Rn + imm32; 9995d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice else 9996d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice offset_addr = Rn - imm32; 9997d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9998d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // address = if index then offset_addr else R[n]; 9999d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice addr_t address; 10000d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (index) 10001d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice address = offset_addr; 10002d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice else 10003d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice address = Rn; 10004d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 10005c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10006c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10007c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 10008c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10009d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice EmulateInstruction::Context context; 10010d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.type = eContextRegisterStore; 10011d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10012d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 10013d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10014d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t Rt = ReadCoreReg (t, &success); 10015d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!success) 10016d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 10017d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 10018d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (t == 15) 10019d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 10020e98b958df160cef9f2e816b4d86342f42a1c4025Caroline Tice uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10021d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!success) 10022d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 10023d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 10024d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10025d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 10026d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice } 10027d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice else 10028d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 10029d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!MemUWrite (context, address, Rt, addr_byte_size)) 10030d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 10031d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice } 10032d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 10033d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // if wback then R[n] = offset_addr; 10034d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (wback) 10035d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 10036d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.type = eContextAdjustBaseRegister; 10037d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.SetImmediate (offset_addr); 10038d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 10039d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10040d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 10041d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10042d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10043d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 10044d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10045d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10046d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.66 LDRD (immediate) 100471697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 100481697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10049d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 10050d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10051d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 10052d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 100531697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if ConditionPassed() then 100541697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 100551697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 100561697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice address = if index then offset_addr else R[n]; 100571697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice R[t] = MemA[address,4]; 100581697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice R[t2] = MemA[address+4,4]; 100591697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if wback then R[n] = offset_addr; 10060d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 10061d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 100621697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool success = false; 10063d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10064d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 10065d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 100661697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t t; 100671697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t t2; 100681697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t n; 100691697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t imm32; 100701697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool index; 100711697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool add; 100721697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool wback; 100731697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 10074d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 10075d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 100761697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice case eEncodingT1: 10077061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //if P == �0� && W == �0� then SEE �Related encodings�; 10078061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //if Rn == �1111� then SEE LDRD (literal); 10079061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 100801697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t = Bits32 (opcode, 15, 12); 100811697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t2 = Bits32 (opcode, 11, 8); 100821697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice n = Bits32 (opcode, 19, 16); 100831697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 100841697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 10085061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 100861697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice index = BitIsSet (opcode, 24); 100871697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice add = BitIsSet (opcode, 23); 100881697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice wback = BitIsSet (opcode, 21); 100891697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 100901697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if wback && (n == t || n == t2) then UNPREDICTABLE; 100911697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (wback && ((n == t) || (n == t2))) 100921697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 100931697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 100941697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 100951697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (BadReg (t) || BadReg (t2) || (t == t2)) 100961697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 100971697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 100981697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice break; 100991697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101001697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice case eEncodingA1: 10101061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //if Rn == �1111� then SEE LDRD (literal); 10102061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //if Rt<0> == �1� then UNPREDICTABLE; 101031697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 101041697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t = Bits32 (opcode, 15, 12); 10105eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (BitIsSet (t, 0)) 10106eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 101071697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t2 = t + 1; 101081697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice n = Bits32 (opcode, 19, 16); 101091697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 101101697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 10111061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 101121697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice index = BitIsSet (opcode, 24); 101131697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice add = BitIsSet (opcode, 23); 101141697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 101151697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 10116061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //if P == �0� && W == �1� then UNPREDICTABLE; 101171697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 101181697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101191697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101201697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if wback && (n == t || n == t2) then UNPREDICTABLE; 101211697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (wback && ((n == t) || (n == t2))) 101221697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101231697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101241697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if t2 == 15 then UNPREDICTABLE; 101251697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (t2 == 15) 101261697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101271697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101281697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice break; 101291697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101301697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice default: 101311697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101321697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice } 101331697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101341697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 101351697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 101361697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!success) 101371697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101381697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101391697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice addr_t offset_addr; 101401697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (add) 101411697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice offset_addr = Rn + imm32; 101421697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice else 101431697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice offset_addr = Rn - imm32; 101441697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101451697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //address = if index then offset_addr else R[n]; 101461697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice addr_t address; 101471697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (index) 101481697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice address = offset_addr; 101491697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice else 101501697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice address = Rn; 101511697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101521697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //R[t] = MemA[address,4]; 10153c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10154c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 101551697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101561697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice EmulateInstruction::Context context; 101571697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.type = eContextRegisterLoad; 101581697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 101591697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101601697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 101611697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 101621697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!success) 101631697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101641697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101651697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 101661697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101671697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101681697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //R[t2] = MemA[address+4,4]; 101691697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101701697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 101711697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice data = MemARead (context, address + 4, addr_byte_size, 0, &success); 101721697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!success) 101731697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101741697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101751697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 101761697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 101771697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101781697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if wback then R[n] = offset_addr; 101791697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (wback) 101801697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice { 101811697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.type = eContextAdjustBaseRegister; 101821697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.SetAddress (offset_addr); 101831697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 101841697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 101851697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 10186d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10187d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10188d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 10189d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10190d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10191d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.68 LDRD (register) 10192eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10193eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10194d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 10195d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10196d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 10197d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 10198eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if ConditionPassed() then 10199eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice EncodingSpecificOperations(); 10200eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10201eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice address = if index then offset_addr else R[n]; 10202eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice R[t] = MemA[address,4]; 10203eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice R[t2] = MemA[address+4,4]; 10204eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if wback then R[n] = offset_addr; 10205d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 10206d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10207eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool success = false; 10208d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10209d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 10210d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 10211eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t t; 10212eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t t2; 10213eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t n; 10214eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t m; 10215eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool index; 10216eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool add; 10217eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool wback; 10218d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10219d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 10220d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 10221eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice case eEncodingA1: 10222061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rt<0> == �1� then UNPREDICTABLE; 10223eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10224eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice t = Bits32 (opcode, 15, 12); 10225eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (BitIsSet (t, 0)) 10226eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10227eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice t2 = t + 1; 10228eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice n = Bits32 (opcode, 19, 16); 10229eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice m = Bits32 (opcode, 3, 0); 10230d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10231061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10232eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice index = BitIsSet (opcode, 24); 10233eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice add = BitIsSet (opcode, 23); 10234eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10235d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10236061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && W == �1� then UNPREDICTABLE; 10237eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10238eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10239d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10240eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10241eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10242eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10243d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10244eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10245eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (wback && ((n == 15) || (n == t) || (n == t2))) 10246eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10247d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10248eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10249eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if ((ArchVersion() < 6) && wback && (m == n)) 10250eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10251eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice break; 10252d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10253eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice default: 10254eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10255d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10256d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10257eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 10258eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10259eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10260c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10261c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10262d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10263eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 10264eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10265eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10266c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 10267c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10268d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10269eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10270eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice addr_t offset_addr; 10271eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (add) 10272eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_addr = Rn + Rm; 10273eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice else 10274eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_addr = Rn - Rm; 10275d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10276eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // address = if index then offset_addr else R[n]; 10277eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice addr_t address; 10278eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (index) 10279eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice address = offset_addr; 10280eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice else 10281eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice address = Rn; 10282d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10283eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice EmulateInstruction::Context context; 10284eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.type = eContextRegisterLoad; 10285eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10286d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10287eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // R[t] = MemA[address,4]; 10288eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 10289eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10290eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10291eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10292d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10293eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10294eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10295d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10296eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // R[t2] = MemA[address+4,4]; 10297d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10298eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10299eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10300eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10301d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10302eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10303eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10304d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10305eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if wback then R[n] = offset_addr; 10306eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (wback) 10307d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 10308eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.type = eContextAdjustBaseRegister; 10309eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.SetAddress (offset_addr); 10310d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10311eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10312eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10313d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10314d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10315d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 10316d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10317d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10318d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.200 STRD (immediate) 1031974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 1032074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice// stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10321d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 10322d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10323d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 10324d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 1032574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if ConditionPassed() then 1032674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 1032774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1032874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice address = if index then offset_addr else R[n]; 1032974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice MemA[address,4] = R[t]; 1033074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice MemA[address+4,4] = R[t2]; 1033174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if wback then R[n] = offset_addr; 10332d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 10333d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 1033474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool success = false; 1033574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1033674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (ConditionPassed(opcode)) 1033774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice { 1033874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t t; 1033974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t t2; 1034074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t n; 1034174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t imm32; 1034274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool index; 1034374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool add; 1034474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool wback; 1034574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1034674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice switch (encoding) 1034774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice { 1034874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice case eEncodingT1: 10349061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && W == �0� then SEE �Related encodings�; 10350061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 1035174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice t = Bits32 (opcode, 15, 12); 1035274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice t2 = Bits32 (opcode, 11, 8); 1035374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice n = Bits32 (opcode, 19, 16); 1035474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 1035574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10356061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 1035774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice index = BitIsSet (opcode, 24); 1035874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice add = BitIsSet (opcode, 23); 1035974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice wback = BitIsSet (opcode, 21); 1036074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1036174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if wback && (n == t || n == t2) then UNPREDICTABLE; 1036274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (wback && ((n == t) || (n == t2))) 1036374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1036474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1036574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 1036674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if ((n == 15) || BadReg (t) || BadReg (t2)) 1036774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1036874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1036974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice break; 1037074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1037174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice case eEncodingA1: 10372061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rt<0> == �1� then UNPREDICTABLE; 1037374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 1037474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice t = Bits32 (opcode, 15, 12); 1037574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (BitIsSet (t, 0)) 1037674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1037774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1037874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice t2 = t + 1; 1037974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice n = Bits32 (opcode, 19, 16); 1038074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 1038174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10382061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 1038374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice index = BitIsSet (opcode, 24); 1038474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice add = BitIsSet (opcode, 23); 1038574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 1038674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10387061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && W == �1� then UNPREDICTABLE; 1038874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 1038974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1039074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1039174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 1039274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (wback && ((n == 15) || (n == t) || (n == t2))) 1039374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1039474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1039574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if t2 == 15 then UNPREDICTABLE; 1039674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (t2 == 15) 1039774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1039874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1039974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice break; 1040074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1040174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice default: 1040274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1040374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice } 1040474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10405c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10406c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 1040774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1040874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 1040974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1041074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1041174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1041274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1041374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice addr_t offset_addr; 1041474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (add) 1041574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice offset_addr = Rn + imm32; 1041674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice else 1041774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice offset_addr = Rn - imm32; 10418d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 1041974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice //address = if index then offset_addr else R[n]; 1042074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice addr_t address; 1042174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (index) 1042274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice address = offset_addr; 1042374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice else 1042474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice address = Rn; 1042574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1042674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice //MemA[address,4] = R[t]; 10427c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 10428c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 1042974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1043074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t data = ReadCoreReg (t, &success); 1043174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1043274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1043374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1043474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice EmulateInstruction::Context context; 1043574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.type = eContextRegisterStore; 1043674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 1043774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1043874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 1043974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1044074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!MemAWrite (context, address, data, addr_byte_size)) 1044174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1044274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1044374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice //MemA[address+4,4] = R[t2]; 10444c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 1044574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 1044674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1044774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice data = ReadCoreReg (t2, &success); 1044874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1044974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1045074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1045174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!MemAWrite (context, address + 4, data, addr_byte_size)) 1045274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1045374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1045474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice //if wback then R[n] = offset_addr; 1045574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (wback) 1045674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice { 1045774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.type = eContextAdjustBaseRegister; 1045874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.SetAddress (offset_addr); 1045974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1046074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 1046174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1046274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice } 1046374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice } 10464d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 10465d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10466d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10467d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10468d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.201 STRD (register) 10469d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 10470d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10471d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 10472d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 1047374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if ConditionPassed() then 1047474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice EncodingSpecificOperations(); 1047574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 1047674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice address = if index then offset_addr else R[n]; 1047774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice MemA[address,4] = R[t]; 1047874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice MemA[address+4,4] = R[t2]; 1047974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if wback then R[n] = offset_addr; 10480d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 10481d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 1048274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool success = false; 1048374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1048474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (ConditionPassed(opcode)) 1048574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice { 1048674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t t; 1048774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t t2; 1048874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t n; 1048974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t m; 1049074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool index; 1049174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool add; 1049274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice bool wback; 10493d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 1049474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice switch (encoding) 1049574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice { 1049674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice case eEncodingA1: 10497061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if Rt<0> == �1� then UNPREDICTABLE; 1049874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 1049974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice t = Bits32 (opcode, 15, 12); 1050074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (BitIsSet (t, 0)) 1050174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1050274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1050374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice t2 = t+1; 1050474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice n = Bits32 (opcode, 19, 16); 1050574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice m = Bits32 (opcode, 3, 0); 1050674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10507061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 1050874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice index = BitIsSet (opcode, 24); 1050974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice add = BitIsSet (opcode, 23); 1051074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 1051174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10512061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && W == �1� then UNPREDICTABLE; 1051374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 1051474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1051574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1051674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if t2 == 15 || m == 15 then UNPREDICTABLE; 1051774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if ((t2 == 15) || (m == 15)) 1051874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1051974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1052074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 1052174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (wback && ((n == 15) || (n == t) || (n == t2))) 1052274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1052374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1052474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 105254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ((ArchVersion() < 6) && wback && (m == n)) 1052674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1052774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1052874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice break; 1052974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1053074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice default: 1053174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1053274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice } 1053374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10534c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10535c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10536c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo offset_reg; 10537c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10538c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 1053974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1054074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 1054174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1054274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1054374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1054474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 1054574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1054674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1054774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1054874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 1054974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice addr_t offset_addr; 1055074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (add) 1055174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice offset_addr = Rn + Rm; 1055274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice else 1055374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice offset_addr = Rn - Rm; 1055474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1055574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // address = if index then offset_addr else R[n]; 1055674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice addr_t address; 1055774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (index) 1055874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice address = offset_addr; 1055974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice else 1056074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice address = Rn; 1056174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // MemA[address,4] = R[t]; 1056274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t Rt = ReadCoreReg (t, &success); 1056374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1056474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1056574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1056674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice EmulateInstruction::Context context; 1056774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.type = eContextRegisterStore; 10568c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 1056974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 1057074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1057174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 1057274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1057374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!MemAWrite (context, address, Rt, addr_byte_size)) 1057474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1057574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1057674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // MemA[address+4,4] = R[t2]; 1057774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice uint32_t Rt2 = ReadCoreReg (t2, &success); 1057874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!success) 1057974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1058074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 10581c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 1058274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1058374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 1058474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1058574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 1058674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1058774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1058874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice // if wback then R[n] = offset_addr; 1058974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (wback) 1059074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice { 1059174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.type = eContextAdjustBaseRegister; 1059274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice context.SetAddress (offset_addr); 1059374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1059474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 1059574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice return false; 1059674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice 1059774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice } 1059874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice } 1059924bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton return true; 10600d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10601d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 106024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice// A8.6.319 VLDM 106034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 106044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice// an ARM core register. 106054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Ticebool 106064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline TiceEmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 106074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice{ 106084f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#if 0 106094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ConditionPassed() then 106104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 106114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice address = if add then R[n] else R[n]-imm32; 10612c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 106134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice for r = 0 to regs-1 106144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if single_regs then 106154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice S[d+r] = MemA[address,4]; address = address+4; 106164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice else 106174f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 106184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // Combine the word-aligned words in the correct order for current endianness. 106194f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice D[d+r] = if BigEndian() then word1:word2 else word2:word1; 106204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#endif 106214f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice bool success = false; 106234f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (ConditionPassed(opcode)) 106254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 10626bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool single_regs; 10627bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool add; 10628bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool wback; 10629bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t d; 10630bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t n; 10631bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t imm32; 10632bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t regs; 10633bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 106344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice switch (encoding) 106354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 106364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice case eEncodingT1: 106374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice case eEncodingA1: 10638061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10639061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10640061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �1� && W == �0� then SEE VLDR; 10641061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == U && W == �1� then UNDEFINED; 106424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 106434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 106444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10646061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 106474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice single_regs = false; 106484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice add = BitIsSet (opcode, 23); 106494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice wback = BitIsSet (opcode, 21); 106504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 10651061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 106524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 106534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice n = Bits32 (opcode, 19, 16); 106544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 106554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 10656061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 106574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice regs = Bits32 (opcode, 7, 0) / 2; 106584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 106604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 106614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 106624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 106644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 106654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 106664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice break; 106684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice case eEncodingT2: 106704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice case eEncodingA2: 10671061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10672061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10673061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �1� && W == �0� then SEE VLDR; 10674061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == U && W == �1� then UNDEFINED; 106754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 106764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 106774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10679061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 106804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice single_regs = true; 106814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice add = BitIsSet (opcode, 23); 106824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice wback = BitIsSet (opcode, 21); 106834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 106844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice n = Bits32 (opcode, 19, 16); 106854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 10686061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 106874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 106884f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice regs = Bits32 (opcode, 7, 0); 106894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106904f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 106914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 106924f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 106934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106944f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 106954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if ((regs == 0) || ((d + regs) > 32)) 106964f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 106974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice break; 106984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 106994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice default: 107004f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 10703c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10704c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 107054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 107074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!success) 107084f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // address = if add then R[n] else R[n]-imm32; 107114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice addr_t address; 107124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (add) 107134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice address = Rn; 107144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice else 107154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice address = Rn - imm32; 107164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 10717c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 107184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice EmulateInstruction::Context context; 107194f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (wback) 107214f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 107224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint32_t value; 107234f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (add) 107244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice value = Rn + imm32; 107254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice else 107264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice value = Rn - imm32; 107274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice context.type = eContextAdjustBaseRegister; 107294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice context.SetImmediateSigned (value - Rn); 107304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 107314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 107364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 107374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice context.type = eContextRegisterLoad; 107394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // for r = 0 to regs-1 10741bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice for (uint32_t r = 0; r < regs; ++r) 107424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 107434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (single_regs) 107444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 107454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // S[d+r] = MemA[address,4]; address = address+4; 107464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 107474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 107494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!success) 107504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 107534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice address = address + 4; 107564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice else 107584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 107594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 107604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 107614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 107624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!success) 107634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 107664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 107674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!success) 107684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice address = address + 8; 107714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // // Combine the word-aligned words in the correct order for current endianness. 107724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 107734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice uint64_t data; 10774888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (GetByteOrder() == eByteOrderBig) 107754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 107764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice data = word1; 107774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice data = (data << 32) | word2; 107784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice else 107804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 107814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice data = word2; 107824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice data = (data << 32) | word1; 107834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice 107854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 107864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return false; 107874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107884f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice } 107904f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice return true; 107914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice} 10792bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10793bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice// A8.6.399 VSTM 10794917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10795917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// ARM core register. 10796bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Ticebool 10797bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline TiceEmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10798bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice{ 10799bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice#if 0 10800bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ConditionPassed() then 10801bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10802bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice address = if add then R[n] else R[n]-imm32; 10803c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10804bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice for r = 0 to regs-1 10805bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if single_regs then 10806bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice MemA[address,4] = S[d+r]; address = address+4; 10807bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice else 10808bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // Store as two word-aligned words in the correct order for current endianness. 10809bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10810bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10811bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice address = address+8; 10812bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice#endif 10813bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10814bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool success = false; 10815bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10816bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (ConditionPassed (opcode)) 10817bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10818bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool single_regs; 10819bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool add; 10820bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice bool wback; 10821bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t d; 10822bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t n; 10823bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t imm32; 10824bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t regs; 10825bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10826bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice switch (encoding) 10827bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10828bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice case eEncodingT1: 10829bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice case eEncodingA1: 10830061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10831061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10832061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �1� && W == �0� then SEE VSTR; 10833061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == U && W == �1� then UNDEFINED; 10834bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10835bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10836bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10837bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10838061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10839bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice single_regs = false; 10840bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice add = BitIsSet (opcode, 23); 10841bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice wback = BitIsSet (opcode, 21); 10842bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10843061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10844bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10845bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice n = Bits32 (opcode, 19, 16); 10846bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 10847bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10848061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10849bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice regs = Bits32 (opcode, 7, 0) / 2; 10850bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10851bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10852bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10853bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10854bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10855bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10856bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10857bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10858bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10859bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice break; 10860bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10861bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice case eEncodingT2: 10862bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice case eEncodingA2: 10863061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10864061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10865061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == �1� && W == �0� then SEE VSTR; 10866061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if P == U && W == �1� then UNDEFINED; 10867bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10868bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10869bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10870bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10871061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10872bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice single_regs = true; 10873bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice add = BitIsSet (opcode, 23); 10874bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice wback = BitIsSet (opcode, 21); 10875bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10876bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice n = Bits32 (opcode, 19, 16); 10877bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10878061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10879bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 10880bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice regs = Bits32 (opcode, 7, 0); 10881bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10882bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10883bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10884bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10885bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10886bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10887bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if ((regs == 0) || ((d + regs) > 32)) 10888bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10889bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10890bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice break; 10891bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10892bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice default: 10893bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10894bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10895bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10896c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 10897c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10898bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10899bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 10900bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!success) 10901bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10902bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10903bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // address = if add then R[n] else R[n]-imm32; 10904bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice addr_t address; 10905bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (add) 10906bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice address = Rn; 10907bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice else 10908bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice address = Rn - imm32; 10909bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10910bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice EmulateInstruction::Context context; 10911c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10912bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (wback) 10913bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10914bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t value; 10915bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (add) 10916bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice value = Rn + imm32; 10917bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice else 10918bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice value = Rn - imm32; 10919bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10920bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.type = eContextAdjustBaseRegister; 10921bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.SetRegisterPlusOffset (base_reg, value - Rn); 10922bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10923bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10924bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10925bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10926bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10927bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 10928bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10929bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10930bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.type = eContextRegisterStore; 10931bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // for r = 0 to regs-1 10932bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice for (int r = 0; r < regs; ++r) 10933bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10934c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 10935bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (single_regs) 10936bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10937bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // MemA[address,4] = S[d+r]; address = address+4; 10938bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10939bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!success) 10940bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10941c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 10942c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 10943c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10944bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10945bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!MemAWrite (context, address, data, addr_byte_size)) 10946bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10947bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10948bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice address = address + 4; 10949bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10950bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice else 10951bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10952bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // // Store as two word-aligned words in the correct order for current endianness. 10953bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10954bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10955bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10956bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!success) 10957bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10958bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10959c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 10960c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10961bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10962888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (GetByteOrder() == eByteOrderBig) 10963bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10964bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10965bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10966bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10967bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10968bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10969bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10970bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10971bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10972bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice else 10973bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice { 10974bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10975bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10976bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10977bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10978bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10979bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10980bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return false; 10981bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10982bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice // address = address+8; 10983bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice address = address + 8; 10984bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10985bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10986bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice } 10987bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice return true; 10988bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice} 10989bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 10990917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// A8.6.320 10991917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 10992917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// an optional offset. 10993917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Ticebool 10994917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline TiceEmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 10995917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice{ 10996917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice#if 0 10997917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if ConditionPassed() then 10998917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10999917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice base = if n == 15 then Align(PC,4) else R[n]; 11000917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice address = if add then (base + imm32) else (base - imm32); 11001917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if single_reg then 11002917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice S[d] = MemA[address,4]; 11003917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice else 11004917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11005917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // Combine the word-aligned words in the correct order for current endianness. 11006917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice D[d] = if BigEndian() then word1:word2 else word2:word1; 11007917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice#endif 11008917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11009917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice bool success = false; 11010917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11011917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (ConditionPassed (opcode)) 11012917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice { 11013917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice bool single_reg; 11014917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice bool add; 11015917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t imm32; 11016917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t d; 11017917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t n; 11018917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11019917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice switch (encoding) 11020917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice { 11021917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice case eEncodingT1: 11022917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice case eEncodingA1: 11023061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11024917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice single_reg = false; 11025917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice add = BitIsSet (opcode, 23); 11026917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 11027917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11028917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // d = UInt(D:Vd); n = UInt(Rn); 11029917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11030917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice n = Bits32 (opcode, 19, 16); 11031917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11032917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice break; 11033917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11034917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice case eEncodingT2: 11035917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice case eEncodingA2: 11036061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11037917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice single_reg = true; 11038917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice add = BitIsSet (opcode, 23); 11039917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 11040917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11041917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // d = UInt(Vd:D); n = UInt(Rn); 11042917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11043917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice n = Bits32 (opcode, 19, 16); 11044917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11045917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice break; 11046917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11047917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice default: 11048917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11049917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice } 11050c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11051c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11052917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11053917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 11054917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (!success) 11055917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11056917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11057917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // base = if n == 15 then Align(PC,4) else R[n]; 11058917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t base; 11059917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (n == 15) 11060917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice base = AlignPC (Rn); 11061917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice else 11062917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice base = Rn; 11063917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11064917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // address = if add then (base + imm32) else (base - imm32); 11065917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice addr_t address; 11066917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (add) 11067917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice address = base + imm32; 11068917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice else 11069917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice address = base - imm32; 11070917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11071917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 11072917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11073917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11074917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice EmulateInstruction::Context context; 11075917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice context.type = eContextRegisterLoad; 11076917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 11077bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice 11078917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (single_reg) 11079917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice { 11080917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // S[d] = MemA[address,4]; 11081917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11082917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (!success) 11083917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11084917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11085917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11086917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11087917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice } 11088917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice else 11089917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice { 11090917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11091917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11092917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (!success) 11093917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11094917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11095917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11096917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11097917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (!success) 11098917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11099917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // // Combine the word-aligned words in the correct order for current endianness. 11100917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice // D[d] = if BigEndian() then word1:word2 else word2:word1; 11101917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice uint64_t data64; 11102888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (GetByteOrder() == eByteOrderBig) 11103917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice { 11104917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice data64 = word1; 11105917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice data64 = (data64 << 32) | word2; 11106917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice } 11107917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice else 11108917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice { 11109917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice data64 = word2; 11110917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice data64 = (data64 << 32) | word1; 11111917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice } 11112917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice 11113917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11114917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return false; 11115917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice } 11116917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice } 11117917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice return true; 11118917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice} 11119424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11120424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice// A8.6.400 VSTR 11121424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11122424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice// optional offset. 11123424652f4258d968dffb5175c4649f6f8afef4217Caroline Ticebool 11124424652f4258d968dffb5175c4649f6f8afef4217Caroline TiceEmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11125424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice{ 11126424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice#if 0 11127424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if ConditionPassed() then 11128424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11129424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice address = if add then (R[n] + imm32) else (R[n] - imm32); 11130424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if single_reg then 11131424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice MemA[address,4] = S[d]; 11132424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice else 11133424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // Store as two word-aligned words in the correct order for current endianness. 11134424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11135424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11136424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice#endif 11137424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11138424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice bool success = false; 11139424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11140424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (ConditionPassed (opcode)) 11141424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice { 11142424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice bool single_reg; 11143424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice bool add; 11144424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint32_t imm32; 11145424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint32_t d; 11146424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint32_t n; 11147424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11148424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice switch (encoding) 11149424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice { 11150424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice case eEncodingT1: 11151424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice case eEncodingA1: 11152061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11153424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice single_reg = false; 11154424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice add = BitIsSet (opcode, 23); 11155424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 11156424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11157424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // d = UInt(D:Vd); n = UInt(Rn); 11158424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11159424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice n = Bits32 (opcode, 19, 16); 11160424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11161424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11162424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11163424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11164424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11165424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice break; 11166424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11167424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice case eEncodingT2: 11168424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice case eEncodingA2: 11169061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11170424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice single_reg = true; 11171424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice add = BitIsSet (opcode, 23); 11172424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 11173424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11174424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // d = UInt(Vd:D); n = UInt(Rn); 11175424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 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 default: 11185424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11186424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice } 11187424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11188c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11189c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11190424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11191424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 11192424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!success) 11193424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11194424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11195424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // address = if add then (R[n] + imm32) else (R[n] - imm32); 11196424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice addr_t address; 11197424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (add) 11198424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice address = Rn + imm32; 11199424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice else 11200424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice address = Rn - imm32; 11201424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11202424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 11203424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11204424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11205c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 11206c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11207424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice EmulateInstruction::Context context; 11208424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice context.type = eContextRegisterStore; 11209424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11210424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11211424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (single_reg) 11212424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice { 11213424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // MemA[address,4] = S[d]; 11214424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11215424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!success) 11216424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11217424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11218424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!MemAWrite (context, address, data, addr_byte_size)) 11219424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11220424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice } 11221424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice else 11222424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice { 11223424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // // Store as two word-aligned words in the correct order for current endianness. 11224424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11225424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11226424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11227424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!success) 11228424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11229424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11230888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (GetByteOrder() == eByteOrderBig) 11231424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice { 11232424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11233424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11234424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11235424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11236424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11237424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11238424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice } 11239424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice else 11240424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice { 11241424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11242424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11243424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice 11244424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11245424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11246424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return false; 11247424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice } 11248424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice } 11249424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice } 11250424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice return true; 11251424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice} 112529121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 112539121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice// A8.6.307 VLDI1 (multiple single elements) 112549121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 112559121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice// element of each register is loaded. 112569121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Ticebool 112579121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline TiceEmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 112589121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice{ 112599121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice#if 0 112609121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if ConditionPassed() then 112619121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 112629121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 112639121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 112649121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice for r = 0 to regs-1 112659121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice for e = 0 to elements-1 112669121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice Elem[D[d+r],e,esize] = MemU[address,ebytes]; 112679121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice address = address + ebytes; 112689121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice#endif 112699121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 112709121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice bool success = false; 112719121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 112729121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (ConditionPassed (opcode)) 112739121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 112749121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t regs; 112759121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t alignment; 112769121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t ebytes; 112779121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t esize; 112789121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t elements; 112799121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t d; 112809121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t n; 112819121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t m; 112829121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice bool wback; 112839121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice bool register_index; 112849121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 112859121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice switch (encoding) 112869121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 112879121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice case eEncodingT1: 112889121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice case eEncodingA1: 112899121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 112909121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // case type of 11291061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // when �0111� 11292061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = 1; if align<1> == �1� then UNDEFINED; 11293061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // when �1010� 11294061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = 2; if align == �11� then UNDEFINED; 11295061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // when �0110� 11296061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = 3; if align<1> == �1� then UNDEFINED; 11297061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // when �0010� 112989121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // regs = 4; 112999121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // otherwise 11300061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // SEE �Related encodings�; 113019121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t type = Bits32 (opcode, 11, 8); 113029121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t align = Bits32 (opcode, 5, 4); 113039121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (type == 7) // '0111' 113049121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 113059121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice regs = 1; 113069121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (BitIsSet (align, 1)) 113079121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113089121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113099121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice else if (type == 10) // '1010' 113109121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 113119121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice regs = 2; 113129121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (align == 3) 113139121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113149121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113159121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113169121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice else if (type == 6) // '0110' 113179121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 113189121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice regs = 3; 113199121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (BitIsSet (align, 1)) 113209121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113219121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113229121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice else if (type == 2) // '0010' 113239121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 113249121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice regs = 4; 113259121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113269121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice else 113279121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113289121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 11329061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // alignment = if align == �00� then 1 else 4 << UInt(align); 113309121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (align == 0) 113319121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice alignment = 1; 113329121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice else 113339121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice alignment = 4 << align; 113349121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113359121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 113369121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice ebytes = 1 << Bits32 (opcode, 7, 6); 113379121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice esize = 8 * ebytes; 113389121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice elements = 8 / ebytes; 113399121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113409121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 113419121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 113429121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice n = Bits32 (opcode, 19, 15); 113439121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice m = Bits32 (opcode, 3, 0); 113449121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113459121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // wback = (m != 15); register_index = (m != 15 && m != 13); 113469121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice wback = (m != 15); 113479121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice register_index = ((m != 15) && (m != 13)); 113489121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113499121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // if d+regs > 32 then UNPREDICTABLE; 113509121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if ((d + regs) > 32) 113519121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113529121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113539121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice break; 113549121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113559121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice default: 113569121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113579121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113589121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 11359c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11360c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 113619121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113629121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 113639121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (!success) 113649121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113659121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113669121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 113679121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice addr_t address = Rn; 113689121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if ((address % alignment) != 0) 113699121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113709121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113719121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice EmulateInstruction::Context context; 113729121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 113739121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (wback) 113749121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 113759121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t Rm = ReadCoreReg (m, &success); 113769121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (!success) 113779121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113789121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113799121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t offset; 113809121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (register_index) 113819121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice offset = Rm; 113829121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice else 113839121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice offset = 8 * regs; 113849121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113859121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint32_t value = Rn + offset; 113869121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice context.type = eContextAdjustBaseRegister; 113879121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice context.SetRegisterPlusOffset (base_reg, offset); 113889121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113899121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 113909121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 113919121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113929121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 113939121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 113949121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // for r = 0 to regs-1 113959121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice for (int r = 0; r < regs; ++r) 113969121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 113979121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // for e = 0 to elements-1 113989121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint64_t assembled_data = 0; 113999121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice for (int e = 0; e < elements; ++e) 114009121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 114019121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 114029121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice context.type = eContextRegisterLoad; 114039121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 114049121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice uint64_t data = MemURead (context, address, ebytes, 0, &success); 114059121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (!success) 114069121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 114079121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 114089121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 114099121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 114109121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice // address = address + ebytes; 114119121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice address = address + ebytes; 114129121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 114139121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 114149121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return false; 114159121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 114169121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice } 114179121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice return true; 114189121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice} 114199121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice 11420b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice// A8.6.308 VLD1 (single element to one lane) 11421b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice// 11422b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Ticebool 11423b6281b1d94e75876211a589bc9c4e2756feab04eCaroline TiceEmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11424b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice{ 11425b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice#if 0 11426b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if ConditionPassed() then 11427b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11428b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11429b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11430b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice Elem[D[d],index,esize] = MemU[address,ebytes]; 11431b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice#endif 11432b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11433b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice bool success = false; 11434b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11435b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (ConditionPassed (opcode)) 11436b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11437b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t ebytes; 11438b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t esize; 11439b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t index; 11440b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t alignment; 11441b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t d; 11442b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t n; 11443b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t m; 11444b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice bool wback; 11445b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice bool register_index; 11446b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11447b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice switch (encoding) 11448b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11449b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice case eEncodingT1: 11450b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice case eEncodingA1: 11451b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11452b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t size = Bits32 (opcode, 11, 10); 11453b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t index_align = Bits32 (opcode, 7, 4); 11454061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if size == �11� then SEE VLD1 (single element to all lanes); 114558d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice if (size == 3) 114568d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice return EmulateVLD1SingleAll (opcode, encoding); 11457b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // case size of 11458b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (size == 0) // when '00' 11459b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11460061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<0> != �0� then UNDEFINED; 11461b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (BitIsClear (index_align, 0)) 11462b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11463b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11464b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11465b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice ebytes = 1; 11466b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice esize = 8; 11467b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice index = Bits32 (index_align, 3, 1); 11468b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice alignment = 1; 11469b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11470061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (size == 1) // when �01� 11471b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11472061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<1> != �0� then UNDEFINED; 11473b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (BitIsClear (index_align, 1)) 11474b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11475b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11476b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11477b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice ebytes = 2; 11478b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice esize = 16; 11479b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice index = Bits32 (index_align, 3, 2); 11480b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11481061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // alignment = if index_align<0> == �0� then 1 else 2; 11482b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (BitIsClear (index_align, 0)) 11483b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice alignment = 1; 11484b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice else 11485b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice alignment = 2; 11486b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11487061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (size == 2) // when �10� 11488b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11489061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<2> != �0� then UNDEFINED; 11490b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (BitIsClear (index_align, 2)) 11491b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11492b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11493061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11494b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11495b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11496b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11497b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11498b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice ebytes = 4; 11499b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice esize = 32; 11500b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice index = Bit32 (index_align, 3); 11501b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11502061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // alignment = if index_align<1:0> == �00� then 1 else 4; 11503b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (Bits32 (index_align, 1, 0) == 0) 11504b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice alignment = 1; 11505b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice else 11506b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice alignment = 4; 11507b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11508b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11509b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11510b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice n = Bits32 (opcode, 19, 16); 11511b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice m = Bits32 (opcode, 3, 0); 11512b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11513b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11514b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice wback = (m != 15); 11515b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice register_index = ((m != 15) && (m != 13)); 11516b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11517b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (n == 15) 11518b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11519b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11520b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11521b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice break; 11522b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11523b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice default: 11524b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11525b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11526b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11527c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11528c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11529b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11530b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 11531b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (!success) 11532b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11533b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11534b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11535b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice addr_t address = Rn; 11536b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if ((address % alignment) != 0) 11537b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11538b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11539b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice EmulateInstruction::Context context; 11540b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11541b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (wback) 11542b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 11543b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t Rm = ReadCoreReg (m, &success); 11544b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (!success) 11545b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11546b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11547b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t offset; 11548b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (register_index) 11549b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice offset = Rm; 11550b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice else 11551b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice offset = ebytes; 11552b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11553b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t value = Rn + offset; 11554b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11555b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice context.type = eContextAdjustBaseRegister; 11556b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice context.SetRegisterPlusOffset (base_reg, offset); 11557b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11558b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11559b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11560b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11561b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11562b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // Elem[D[d],index,esize] = MemU[address,ebytes]; 11563b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint32_t element = MemURead (context, address, esize, 0, &success); 11564b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (!success) 11565b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11566b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11567b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice element = element << (index * esize); 11568b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11569b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11570b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (!success) 11571b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11572b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11573b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint64_t all_ones = -1; 11574b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11575b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // at element & to the right of element. 11576b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (index > 0) 115777b880943399074cc7de69aa02e0da426f52e274eCaroline Tice mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11578b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // now mask should be 0's where element goes & 1's 11579b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice // everywhere else. 11580b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11581b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11582b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11583b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 11584b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice context.type = eContextRegisterLoad; 11585b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11586b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return false; 11587b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice } 11588b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice return true; 11589b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice} 11590b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice 115911e542e30870bbced43d8438d125979dc9522ec07Caroline Tice// A8.6.391 VST1 (multiple single elements) 115921e542e30870bbced43d8438d125979dc9522ec07Caroline Tice// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 115931e542e30870bbced43d8438d125979dc9522ec07Caroline Tice// interleaving. Every element of each register is stored. 115941e542e30870bbced43d8438d125979dc9522ec07Caroline Ticebool 115951e542e30870bbced43d8438d125979dc9522ec07Caroline TiceEmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 115961e542e30870bbced43d8438d125979dc9522ec07Caroline Tice{ 115971e542e30870bbced43d8438d125979dc9522ec07Caroline Tice#if 0 115981e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if ConditionPassed() then 115991e542e30870bbced43d8438d125979dc9522ec07Caroline Tice EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 116001e542e30870bbced43d8438d125979dc9522ec07Caroline Tice address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 116011e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 116021e542e30870bbced43d8438d125979dc9522ec07Caroline Tice for r = 0 to regs-1 116031e542e30870bbced43d8438d125979dc9522ec07Caroline Tice for e = 0 to elements-1 116041e542e30870bbced43d8438d125979dc9522ec07Caroline Tice MemU[address,ebytes] = Elem[D[d+r],e,esize]; 116051e542e30870bbced43d8438d125979dc9522ec07Caroline Tice address = address + ebytes; 116061e542e30870bbced43d8438d125979dc9522ec07Caroline Tice#endif 116071e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116081e542e30870bbced43d8438d125979dc9522ec07Caroline Tice bool success = false; 116091e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116101e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (ConditionPassed (opcode)) 116111e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 116121e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t regs; 116131e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t alignment; 116141e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t ebytes; 116151e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t esize; 116161e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t elements; 116171e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t d; 116181e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t n; 116191e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t m; 116201e542e30870bbced43d8438d125979dc9522ec07Caroline Tice bool wback; 116211e542e30870bbced43d8438d125979dc9522ec07Caroline Tice bool register_index; 116221e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116231e542e30870bbced43d8438d125979dc9522ec07Caroline Tice switch (encoding) 116241e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 116251e542e30870bbced43d8438d125979dc9522ec07Caroline Tice case eEncodingT1: 116261e542e30870bbced43d8438d125979dc9522ec07Caroline Tice case eEncodingA1: 116271e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 116281e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t type = Bits32 (opcode, 11, 8); 116291e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t align = Bits32 (opcode, 5, 4); 116301e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116311e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // case type of 11632061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton if (type == 7) // when �0111� 116331e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 11634061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = 1; if align<1> == �1� then UNDEFINED; 116351e542e30870bbced43d8438d125979dc9522ec07Caroline Tice regs = 1; 116361e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (BitIsSet (align, 1)) 116371e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116381e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 11639061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (type == 10) // when �1010� 116401e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 11641061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = 2; if align == �11� then UNDEFINED; 116421e542e30870bbced43d8438d125979dc9522ec07Caroline Tice regs = 2; 116431e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (align == 3) 116441e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116451e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 11646061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (type == 6) // when �0110� 116471e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 11648061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // regs = 3; if align<1> == �1� then UNDEFINED; 116491e542e30870bbced43d8438d125979dc9522ec07Caroline Tice regs = 3; 116501e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (BitIsSet (align, 1)) 116511e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116521e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 11653061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (type == 2) // when �0010� 116541e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // regs = 4; 116551e542e30870bbced43d8438d125979dc9522ec07Caroline Tice regs = 4; 116561e542e30870bbced43d8438d125979dc9522ec07Caroline Tice else // otherwise 11657061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // SEE �Related encodings�; 116581e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116591e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 11660061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // alignment = if align == �00� then 1 else 4 << UInt(align); 116611e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (align == 0) 11662a1c7e46b8260cba74e04d4ae0f748c602148deb9Johnny Chen alignment = 1; 116631e542e30870bbced43d8438d125979dc9522ec07Caroline Tice else 116641e542e30870bbced43d8438d125979dc9522ec07Caroline Tice alignment = 4 << align; 116651e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116661e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 116671e542e30870bbced43d8438d125979dc9522ec07Caroline Tice ebytes = 1 << Bits32 (opcode,7, 6); 116681e542e30870bbced43d8438d125979dc9522ec07Caroline Tice esize = 8 * ebytes; 116691e542e30870bbced43d8438d125979dc9522ec07Caroline Tice elements = 8 / ebytes; 116701e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116711e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 116721e542e30870bbced43d8438d125979dc9522ec07Caroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 116731e542e30870bbced43d8438d125979dc9522ec07Caroline Tice n = Bits32 (opcode, 19, 16); 116741e542e30870bbced43d8438d125979dc9522ec07Caroline Tice m = Bits32 (opcode, 3, 0); 116751e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116761e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // wback = (m != 15); register_index = (m != 15 && m != 13); 116771e542e30870bbced43d8438d125979dc9522ec07Caroline Tice wback = (m != 15); 116781e542e30870bbced43d8438d125979dc9522ec07Caroline Tice register_index = ((m != 15) && (m != 13)); 116791e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116801e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 116811e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if ((d + regs) > 32) 116821e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116831e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116841e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (n == 15) 116851e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116861e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116871e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 116881e542e30870bbced43d8438d125979dc9522ec07Caroline Tice break; 116891e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116901e542e30870bbced43d8438d125979dc9522ec07Caroline Tice default: 116911e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 116921e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 116931e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 11694c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11695c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 116961e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 116971e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 116981e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (!success) 116991e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 117001e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117011e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 117021e542e30870bbced43d8438d125979dc9522ec07Caroline Tice addr_t address = Rn; 117031e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if ((address % alignment) != 0) 117041e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 117051e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117061e542e30870bbced43d8438d125979dc9522ec07Caroline Tice EmulateInstruction::Context context; 117071e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 117081e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (wback) 117091e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 117101e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 117111e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (!success) 117121e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 117131e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117141e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint32_t offset; 117151e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (register_index) 117161e542e30870bbced43d8438d125979dc9522ec07Caroline Tice offset = Rm; 117171e542e30870bbced43d8438d125979dc9522ec07Caroline Tice else 117181e542e30870bbced43d8438d125979dc9522ec07Caroline Tice offset = 8 * regs; 117191e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117201e542e30870bbced43d8438d125979dc9522ec07Caroline Tice context.type = eContextAdjustBaseRegister; 117211e542e30870bbced43d8438d125979dc9522ec07Caroline Tice context.SetRegisterPlusOffset (base_reg, offset); 117221e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117231e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 117241e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 117251e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 117261e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 11727c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 117281e542e30870bbced43d8438d125979dc9522ec07Caroline Tice context.type = eContextRegisterStore; 117291e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // for r = 0 to regs-1 117301e542e30870bbced43d8438d125979dc9522ec07Caroline Tice for (int r = 0; r < regs; ++r) 117311e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 11732c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 117331e542e30870bbced43d8438d125979dc9522ec07Caroline Tice uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 117341e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (!success) 117351e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 117361e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117371e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // for e = 0 to elements-1 117381e542e30870bbced43d8438d125979dc9522ec07Caroline Tice for (int e = 0; e < elements; ++e) 117391e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 117401e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 117417b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 117421e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117431e542e30870bbced43d8438d125979dc9522ec07Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 117441e542e30870bbced43d8438d125979dc9522ec07Caroline Tice if (!MemUWrite (context, address, word, ebytes)) 117451e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return false; 117461e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117471e542e30870bbced43d8438d125979dc9522ec07Caroline Tice // address = address + ebytes; 117481e542e30870bbced43d8438d125979dc9522ec07Caroline Tice address = address + ebytes; 117491e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 117501e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 117511e542e30870bbced43d8438d125979dc9522ec07Caroline Tice } 117521e542e30870bbced43d8438d125979dc9522ec07Caroline Tice return true; 117531e542e30870bbced43d8438d125979dc9522ec07Caroline Tice} 117541e542e30870bbced43d8438d125979dc9522ec07Caroline Tice 117557b880943399074cc7de69aa02e0da426f52e274eCaroline Tice// A8.6.392 VST1 (single element from one lane) 117567b880943399074cc7de69aa02e0da426f52e274eCaroline Tice// This instruction stores one element to memory from one element of a register. 117577b880943399074cc7de69aa02e0da426f52e274eCaroline Ticebool 117587b880943399074cc7de69aa02e0da426f52e274eCaroline TiceEmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 117597b880943399074cc7de69aa02e0da426f52e274eCaroline Tice{ 117607b880943399074cc7de69aa02e0da426f52e274eCaroline Tice#if 0 117617b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if ConditionPassed() then 117627b880943399074cc7de69aa02e0da426f52e274eCaroline Tice EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 117637b880943399074cc7de69aa02e0da426f52e274eCaroline Tice address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 117647b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 117657b880943399074cc7de69aa02e0da426f52e274eCaroline Tice MemU[address,ebytes] = Elem[D[d],index,esize]; 117667b880943399074cc7de69aa02e0da426f52e274eCaroline Tice#endif 117677b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 117687b880943399074cc7de69aa02e0da426f52e274eCaroline Tice bool success = false; 117697b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 117707b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (ConditionPassed (opcode)) 117717b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 117727b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t ebytes; 117737b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t esize; 117747b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t index; 117757b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t alignment; 117767b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t d; 117777b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t n; 117787b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t m; 117797b880943399074cc7de69aa02e0da426f52e274eCaroline Tice bool wback; 117807b880943399074cc7de69aa02e0da426f52e274eCaroline Tice bool register_index; 117817b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 117827b880943399074cc7de69aa02e0da426f52e274eCaroline Tice switch (encoding) 117837b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 117847b880943399074cc7de69aa02e0da426f52e274eCaroline Tice case eEncodingT1: 117857b880943399074cc7de69aa02e0da426f52e274eCaroline Tice case eEncodingA1: 117867b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 117877b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t size = Bits32 (opcode, 11, 10); 117887b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t index_align = Bits32 (opcode, 7, 4); 117897b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 11790061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if size == �11� then UNDEFINED; 117917b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (size == 3) 117927b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 117937b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 117947b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // case size of 11795061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton if (size == 0) // when �00� 117967b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 11797061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<0> != �0� then UNDEFINED; 117987b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (BitIsClear (index_align, 0)) 117997b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118007b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 118017b880943399074cc7de69aa02e0da426f52e274eCaroline Tice ebytes = 1; 118027b880943399074cc7de69aa02e0da426f52e274eCaroline Tice esize = 8; 118037b880943399074cc7de69aa02e0da426f52e274eCaroline Tice index = Bits32 (index_align, 3, 1); 118047b880943399074cc7de69aa02e0da426f52e274eCaroline Tice alignment = 1; 118057b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 11806061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (size == 1) // when �01� 118077b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 11808061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<1> != �0� then UNDEFINED; 118097b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (BitIsClear (index_align, 1)) 118107b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118117b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118127b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 118137b880943399074cc7de69aa02e0da426f52e274eCaroline Tice ebytes = 2; 118147b880943399074cc7de69aa02e0da426f52e274eCaroline Tice esize = 16; 118157b880943399074cc7de69aa02e0da426f52e274eCaroline Tice index = Bits32 (index_align, 3, 2); 118167b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 11817061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // alignment = if index_align<0> == �0� then 1 else 2; 118187b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (BitIsClear (index_align, 0)) 118197b880943399074cc7de69aa02e0da426f52e274eCaroline Tice alignment = 1; 118207b880943399074cc7de69aa02e0da426f52e274eCaroline Tice else 118217b880943399074cc7de69aa02e0da426f52e274eCaroline Tice alignment = 2; 118227b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 11823061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton else if (size == 2) // when �10� 118247b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 11825061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<2> != �0� then UNDEFINED; 118267b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (BitIsClear (index_align, 2)) 118277b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118287b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 11829061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 118307b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 118317b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118327b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118337b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // ebytes = 4; esize = 32; index = UInt(index_align<3>); 118347b880943399074cc7de69aa02e0da426f52e274eCaroline Tice ebytes = 4; 118357b880943399074cc7de69aa02e0da426f52e274eCaroline Tice esize = 32; 118367b880943399074cc7de69aa02e0da426f52e274eCaroline Tice index = Bit32 (index_align, 3); 118377b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 11838061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // alignment = if index_align<1:0> == �00� then 1 else 4; 118397b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (Bits32 (index_align, 1, 0) == 0) 118407b880943399074cc7de69aa02e0da426f52e274eCaroline Tice alignment = 1; 118417b880943399074cc7de69aa02e0da426f52e274eCaroline Tice else 118427b880943399074cc7de69aa02e0da426f52e274eCaroline Tice alignment = 4; 118437b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 118447b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 118457b880943399074cc7de69aa02e0da426f52e274eCaroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 118467b880943399074cc7de69aa02e0da426f52e274eCaroline Tice n = Bits32 (opcode, 19, 16); 118477b880943399074cc7de69aa02e0da426f52e274eCaroline Tice m = Bits32 (opcode, 3, 0); 118487b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118497b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 118507b880943399074cc7de69aa02e0da426f52e274eCaroline Tice wback = (m != 15); 118517b880943399074cc7de69aa02e0da426f52e274eCaroline Tice register_index = ((m != 15) && (m != 13)); 118527b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118537b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (n == 15) 118547b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118557b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 118567b880943399074cc7de69aa02e0da426f52e274eCaroline Tice break; 118577b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118587b880943399074cc7de69aa02e0da426f52e274eCaroline Tice default: 118597b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118607b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 118617b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 11862c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11863c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 118647b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118657b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 118667b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (!success) 118677b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118687b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118697b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 118707b880943399074cc7de69aa02e0da426f52e274eCaroline Tice addr_t address = Rn; 118717b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if ((address % alignment) != 0) 118727b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118737b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118747b880943399074cc7de69aa02e0da426f52e274eCaroline Tice EmulateInstruction::Context context; 118757b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 118767b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (wback) 118777b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 118787b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t Rm = ReadCoreReg (m, &success); 118797b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (!success) 118807b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118817b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118827b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint32_t offset; 118837b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (register_index) 118847b880943399074cc7de69aa02e0da426f52e274eCaroline Tice offset = Rm; 118857b880943399074cc7de69aa02e0da426f52e274eCaroline Tice else 118867b880943399074cc7de69aa02e0da426f52e274eCaroline Tice offset = ebytes; 118877b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118887b880943399074cc7de69aa02e0da426f52e274eCaroline Tice context.type = eContextAdjustBaseRegister; 118897b880943399074cc7de69aa02e0da426f52e274eCaroline Tice context.SetRegisterPlusOffset (base_reg, offset); 118907b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118917b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 118927b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118937b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 118947b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 118957b880943399074cc7de69aa02e0da426f52e274eCaroline Tice // MemU[address,ebytes] = Elem[D[d],index,esize]; 118967b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 118977b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (!success) 118987b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 118997b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 119007b880943399074cc7de69aa02e0da426f52e274eCaroline Tice uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 119017b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 11902c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo data_reg; 11903c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 119047b880943399074cc7de69aa02e0da426f52e274eCaroline Tice context.type = eContextRegisterStore; 119057b880943399074cc7de69aa02e0da426f52e274eCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 119067b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 119077b880943399074cc7de69aa02e0da426f52e274eCaroline Tice if (!MemUWrite (context, address, word, ebytes)) 119087b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return false; 119097b880943399074cc7de69aa02e0da426f52e274eCaroline Tice } 119107b880943399074cc7de69aa02e0da426f52e274eCaroline Tice return true; 119117b880943399074cc7de69aa02e0da426f52e274eCaroline Tice} 119127b880943399074cc7de69aa02e0da426f52e274eCaroline Tice 119138d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice// A8.6.309 VLD1 (single element to all lanes) 119148d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice// This instruction loads one element from memory into every element of one or two vectors. 1191593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Ticebool 119168d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline TiceEmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 1191793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice{ 1191893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice#if 0 1191993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if ConditionPassed() then 1192093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 1192193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 1192293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 1192393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice replicated_element = Replicate(MemU[address,ebytes], elements); 1192493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice for r = 0 to regs-1 1192593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice D[d+r] = replicated_element; 1192693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice#endif 1192793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1192893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice bool success = false; 1192993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1193093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (ConditionPassed (opcode)) 1193193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 1193293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t ebytes; 1193393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t elements; 1193493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t regs; 1193593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t alignment; 1193693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t d; 1193793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t n; 1193893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t m; 1193993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice bool wback; 1194093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice bool register_index; 1194193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1194293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice switch (encoding) 1194393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 1194493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice case eEncodingT1: 1194593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice case eEncodingA1: 1194693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 11947061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 1194893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t size = Bits32 (opcode, 7, 6); 1194993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 1195093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1195193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 11952061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 1195393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice ebytes = 1 << size; 1195493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice elements = 8 / ebytes; 1195593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (BitIsClear (opcode, 5)) 1195693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice regs = 1; 1195793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice else 1195893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice regs = 2; 1195993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 11960061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton //alignment = if a == �0� then 1 else ebytes; 1196193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (BitIsClear (opcode, 4)) 1196293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice alignment = 1; 1196393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice else 1196493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice alignment = ebytes; 1196593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1196693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 1196793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 1196893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice n = Bits32 (opcode, 19, 16); 1196993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice m = Bits32 (opcode, 3, 0); 1197093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1197193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice //wback = (m != 15); register_index = (m != 15 && m != 13); 1197293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice wback = (m != 15); 1197393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice register_index = ((m != 15) && (m != 13)); 1197493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1197593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 1197693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if ((d + regs) > 32) 1197793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1197893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1197993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (n == 15) 1198093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1198193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice } 119826ac9e54dfd1d3e4be4326e0f1740e6a5971c4759Johnny Chen break; 1198393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1198493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice default: 119856ac9e54dfd1d3e4be4326e0f1740e6a5971c4759Johnny Chen return false; 1198693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice } 1198793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 11988c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton RegisterInfo base_reg; 11989c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 1199093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1199193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 1199293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (!success) 1199393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1199493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1199593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 1199693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice addr_t address = Rn; 1199793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if ((address % alignment) != 0) 1199893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1199993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1200093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice EmulateInstruction::Context context; 1200193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 1200293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (wback) 1200393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 1200493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t Rm = ReadCoreReg (m, &success); 1200593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (!success) 1200693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1200793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1200893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t offset; 1200993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (register_index) 1201093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice offset = Rm; 1201193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice else 1201293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice offset = ebytes; 1201393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1201493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice context.type = eContextAdjustBaseRegister; 1201593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice context.SetRegisterPlusOffset (base_reg, offset); 1201693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1201793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 1201893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1201993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice } 1202093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1202193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice // replicated_element = Replicate(MemU[address,ebytes], elements); 1202293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1202393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice context.type = eContextRegisterLoad; 1202493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint64_t word = MemURead (context, address, ebytes, 0, &success); 1202593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (!success) 1202693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1202793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1202865f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen uint64_t replicated_element = 0; 1202993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice uint32_t esize = ebytes * 8; 1203093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice for (int e = 0; e < elements; ++e) 1203193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 1203293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 1203393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice // for r = 0 to regs-1 1203493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice for (int r = 0; r < regs; ++r) 1203593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 1203693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice // D[d+r] = replicated_element; 1203793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 1203893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return false; 1203993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice } 1204093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice } 1204193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice return true; 1204293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice} 1204393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice 120441f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice// B6.2.13 SUBS PC, LR and related instructions 120451f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 120461f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 120471f954f59df9ce7bf58d0353ab0949656561210d4Caroline Ticebool 120481f954f59df9ce7bf58d0353ab0949656561210d4Caroline TiceEmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 120491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice{ 120501f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice#if 0 120511f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if ConditionPassed() then 120521f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice EncodingSpecificOperations(); 120531f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if CurrentInstrSet() == InstrSet_ThumbEE then 120541f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice UNPREDICTABLE; 120551f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 120561f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice case opcode of 12057061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0000� result = R[n] AND operand2; // AND 12058061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0001� result = R[n] EOR operand2; // EOR 12059061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12060061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12061061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12062061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12063061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12064061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12065061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1100� result = R[n] OR operand2; // ORR 12066061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1101� result = operand2; // MOV 12067061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1110� result = R[n] AND NOT(operand2); // BIC 12068061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1111� result = NOT(operand2); // MVN 12069061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton CPSRWriteByInstr(SPSR[], �1111�, TRUE); 120701f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice BranchWritePC(result); 120711f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice#endif 120721f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 120731f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice bool success = false; 120741f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 120751f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (ConditionPassed (opcode)) 120761f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 120771f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t n; 120781f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t m; 120791f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t imm32; 120801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice bool register_form; 120811f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice ARM_ShifterType shift_t; 120821f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t shift_n; 120831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t code; 120841f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 120851f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice switch (encoding) 120861f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 120871f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice case eEncodingT1: 120881f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12089061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 120901f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice n = 14; 120911f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice imm32 = Bits32 (opcode, 7, 0); 120921f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice register_form = false; 120931f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice code = 2; 120941f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 120951f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 120961f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (InITBlock() && !LastInITBlock()) 120971f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return false; 120981f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 120991f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121011f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice case eEncodingA1: 121021f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 121031f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice n = Bits32 (opcode, 19, 16); 121041f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice imm32 = ARMExpandImm (opcode); 121051f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice register_form = false; 121061f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice code = Bits32 (opcode, 24, 21); 121071f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121081f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121091f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121101f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice case eEncodingA2: 121111f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 121121f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice n = Bits32 (opcode, 19, 16); 121131f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice m = Bits32 (opcode, 3, 0); 121141f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice register_form = true; 121151f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121161f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 121171f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice shift_n = DecodeImmShiftARM (opcode, shift_t); 121181f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121191f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121201f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121211f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice default: 121221f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return false; 121231f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice } 121241f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121251f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 121261f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t operand2; 121271f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (register_form) 121281f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 121291f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 121301f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (!success) 121311f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return false; 121321f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12133a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12134a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen if (!success) 12135a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen return false; 121361f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice } 121371f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice else 121381f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 121391f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice operand2 = imm32; 121401f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice } 121411f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121421f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 121431f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (!success) 121441f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return false; 121451f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121461f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice AddWithCarryResult result; 121471f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 121481f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // case opcode of 121491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice switch (code) 121501f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 12151061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 0: // when �0000� 121521f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // result = R[n] AND operand2; // AND 121531f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result.result = Rn & operand2; 121541f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121551f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12156061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 1: // when �0001� 121571f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // result = R[n] EOR operand2; // EOR 121581f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result.result = Rn ^ operand2; 121591f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121601f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12161061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 2: // when �0010� 12162061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 121631f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result = AddWithCarry (Rn, ~(operand2), 1); 121641f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121651f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12166061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 3: // when �0011� 12167061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 121681f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result = AddWithCarry (~(Rn), operand2, 1); 121691f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121701f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12171061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 4: // when �0100� 12172061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 121731f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result = AddWithCarry (Rn, operand2, 0); 121741f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121751f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12176061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 5: // when �0101� 121771f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 121781f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result = AddWithCarry (Rn, operand2, APSR_C); 121791f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12181061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 6: // when �0110� 121821f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 121831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result = AddWithCarry (Rn, ~(operand2), APSR_C); 121841f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121851f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12186061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 7: // when �0111� 121871f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 121881f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result = AddWithCarry (~(Rn), operand2, APSR_C); 121891f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121901f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12191061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 10: // when �1100� 121921f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // result = R[n] OR operand2; // ORR 121931f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result.result = Rn | operand2; 121941f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 121951f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12196061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 11: // when �1101� 121971f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // result = operand2; // MOV 121981f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result.result = operand2; 121991f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 122001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12201061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 12: // when �1110� 122021f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // result = R[n] AND NOT(operand2); // BIC 122031f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result.result = Rn & ~(operand2); 122041f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 122051f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 12206061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton case 15: // when �1111� 122071f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // result = NOT(operand2); // MVN 122081f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice result.result = ~(operand2); 122091f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice break; 122101f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 122111f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice default: 122121f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return false; 122131f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice } 12214061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 122151f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 122161f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 122171f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // the best. 122181f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 122191f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice if (!success) 122201f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return false; 122211f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 122221f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice CPSRWriteByInstr (spsr, 15, true); 122231f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 122241f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice // BranchWritePC(result); 122251f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice EmulateInstruction::Context context; 122261f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice context.type = eContextAdjustPC; 122271f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice context.SetImmediate (result.result); 122281f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 122291f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice BranchWritePC (context, result.result); 122301f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice } 122311f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice return true; 122321f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice} 122331f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice 122342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 12235888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 1223664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 122372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 122382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_arm_opcodes[] = 122392b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 122402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 122412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 122422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 122432b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 122454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 122464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 122472b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 122494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 122504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12251e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to ip 122524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 122534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 122544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 122552b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122562b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 122574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 122584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 122592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122602b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push one register 122612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 122624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 122632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 122654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 122664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 122672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 12269587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Epilogue instructions 122702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 122712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 122724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 122734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 122744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 122754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12276b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 12277b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 12278b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 12279b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 122804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 122813b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 122823b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 122833b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 122843b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 122854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12286383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // To resolve ambiguity, "blx <label>" should come before "bl <label>". 122874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 122884f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 122894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12290ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 122914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 1229259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // bxj 122934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12294b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 12295b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 1229628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // Data-processing instructions 1229728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 12298157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 122994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12300157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 123014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 123028fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (immediate) 123034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 123048fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (register) 123054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12306c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // add (register-shifted register) 123070fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12308a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // adr 123094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 123104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12311e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 123124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12313e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 123144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12315b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (immediate) 123164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12317b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (register) 123184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 123192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 123204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 123212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 123224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 123237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 123244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 123257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 123264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12327ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (immediate) 123284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12329ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (register) 123304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 1233190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // rsc (immediate) 123324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 1233390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // rsc (register) 123344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 123359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (immediate) 123364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 123379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (register) 123384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 1233915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // sub (immediate, ARM) 123404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12341c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen // sub (sp minus immediate) 123424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 123434cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // sub (register) 123444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 123452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 123464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 123472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 123484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12349de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 123504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12351de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 123524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12353de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 1235489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // mov (immediate) 123554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 123564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 1235701d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // mov (register) 123584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12359d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 123604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12361d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 123624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 123633847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (immediate) 123644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 123653847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (register) 123664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 1236734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 123684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 1236934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) 123704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 1237182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 123724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 123732ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // asr (register) 123744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 123752ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 123764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 123772ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 123784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 123792ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 123804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 123812ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 123824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12383eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 123844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12385eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 123864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12387eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 123884f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 123895c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 123904f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 123916b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 123926b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice // subs pc, lr and related instructions 123931f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 123941f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 1239528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 1239628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 12397b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 12398b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 123994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 124004f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 124014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 124024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 124034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 124044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 124054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 124064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 124074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 124084f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 124094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 124104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 124114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 124124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 124134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 124144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 124154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 124164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 124179121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 124189121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 124199121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 124209121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12421b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12422b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 1242393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12424fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 12425fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 12426fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 12427fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 124284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 124294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 124304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 124314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 124324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 124334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 124344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 124354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 124364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 124370fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 124384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 124391e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 124401e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 124411e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 124421e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 124431e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 124447b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 124456bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 124466bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 124476bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // Other instructions 124486bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 124494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 124504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 124514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 124524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 124534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 124541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 124552b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 124562b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 124572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124582b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_arm_opcodes; ++i) 124592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 12460888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12461888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton (g_arm_opcodes[i].variants & arm_isa) != 0) 124622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_arm_opcodes[i]; 124632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 124642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 124652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 124662b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 12469888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12470347320d16d98cffaadf3f888569100c43b241068Johnny Chen{ 124712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 124732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_thumb_opcodes[] = 124742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 124752b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 124762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 124772b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 124782b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124792b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 124804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 124814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 124824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 124832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 124854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12486e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to r7 124874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12488e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 124894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 124902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 12491864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen // PC-relative load into register (see also EmulateADDSPRm) 124924f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 124932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 124942b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 124954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 124964f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 124974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 124984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 124994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 125002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 125012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 125024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 125034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 125042b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 125052b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 125062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Epilogue instructions 125072b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 125082b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 125094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 125104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 125114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 125124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 125134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 125144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 125154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12516b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 12517b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 12518b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 12519b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 125204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12521c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 12522c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 12523c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // If Then makes up to four following instructions conditional. 12524c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 1252504d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton // The next 5 opcode _must_ come before the if then instruction 1252604d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 1252704d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 1252804d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 1252904d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 1253004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 1253104d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 125323b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 125333b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 125343b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 125353b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 125363b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 125374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 125384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 125394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 125404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12541383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 125424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12543383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 125444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 125454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12546ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 125474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 1254859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // bxj 125494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 1255053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // compare and branch 125514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 1255260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch byte 125534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 1255460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch halfword 125554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12556b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 12557b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 1255826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Data-processing instructions 1255926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 12560157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 125614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12562157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 125634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 125644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12565157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // add (register) 125664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 1256726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 125684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12569a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // adr 125704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 125714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 125724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12573e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 125744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12575e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 125764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 125774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12578b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (immediate) 125794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12580b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (register) 125814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 125824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 125832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 125844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 125852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 125864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 125874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 125887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 125894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 125907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 125914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 125924f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12593ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (immediate) 125944f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 125954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12596ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (register) 125974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 125989b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (immediate) 125994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 126009b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (register) 126014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 126024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12603dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // add (immediate, Thumb) 126044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 126054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 126064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 126074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 1260815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // sub (immediate, Thumb) 126094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 126104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 126114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 126124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12613c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen // sub (sp minus immediate) 126144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 126154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 126164cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // sub (register) 126174f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 126184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 126192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 126204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 126212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 126224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12623de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 126244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12625de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 126264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 126274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12628de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 126297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 12630338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from high register to high register 126314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12632338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from low register to low register 126334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 126347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // mov{s}<c>.w <Rd>, <Rm> 126354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12636357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // move immediate 126374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 126384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 126394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12640d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 126414f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12642d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 126434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 126444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 1264534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (immediate) 126464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 1264734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (register) 126484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 126494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 1265034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 126514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 126524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 1265334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm both from r0-r7) 126544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 1265534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm not both from r0-r7) 126564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 1265782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 126584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 126594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12660e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // asr (register) 126614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 126624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 126632ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 126644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 126654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 126662ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 126674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 126684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 126692ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 126704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 126714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 126722ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 126734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 126744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12675eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 126764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12677eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 126784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12679eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 126804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 126814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 126825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 126834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 126845c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 126854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 126866b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 126876b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice // subs pc, lr and related instructions 126881f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12689080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 12690080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice //---------------------------------------------------------------------- 12691080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12692080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice // otherwise the wrong instructions will be selected. 12693080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice //---------------------------------------------------------------------- 126946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 12695080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12696080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12697080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 1269826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 12699b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 12700b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 127014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 127024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 127034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 127044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 127054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 127064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 127074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12708baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // Thumb2 PC-relative load into register 127094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 127104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 127114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 127124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 127134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 127140fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 127154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 127164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 127174f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 127184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 127194f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 127204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 127214f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 127224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 127234f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 127244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 127254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 127264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 127274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 127284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 127294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 127304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 127314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 127324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 127334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 127340fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 127359121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 127369121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 127379121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 127389121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12739b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12740b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 1274193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12742fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 12743fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 12744fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 12745fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 127464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 127474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 127484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 127494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 127504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 127514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 127524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 127534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 127544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 127554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 127564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 127574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 127584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 127594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 127604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 127614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 127621e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 127631e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 127641e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 127651e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 127661e542e30870bbced43d8438d125979dc9522ec07Caroline Tice { 0xffb00000, 0xfa000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 127677b880943399074cc7de69aa02e0da426f52e274eCaroline Tice { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 127686bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 127696bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 127706bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // Other instructions 127716bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 127724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 127734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 127744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 127754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 127764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 127774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 127784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 127794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 127802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 127812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 127822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 127832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_thumb_opcodes; ++i) 127842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 12785888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12786888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton (g_thumb_opcodes[i].variants & arm_isa) != 0) 127872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_thumb_opcodes[i]; 127882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 127892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 127902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1279164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1279231e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool 12793395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 1279431e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{ 12795080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice m_arch = arch; 1279631e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton m_arm_isa = 0; 12797940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton const char *arch_cstr = arch.GetArchitectureName (); 12798395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (arch_cstr) 12799395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton { 12800395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12801395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12802395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12803395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12804395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12805395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 1280682a17a29a99ceef3353ac669ed44749d6106212cJason Molenda else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 128071d29a85815ee049b4f30271161c3b494eef41e8cJohnny Chen else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 128081d29a85815ee049b4f30271161c3b494eef41e8cJohnny Chen else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12809663067fa1a4992523d771c823368f54979249cf9Greg Clayton else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12810663067fa1a4992523d771c823368f54979249cf9Greg Clayton else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12811663067fa1a4992523d771c823368f54979249cf9Greg Clayton else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12812663067fa1a4992523d771c823368f54979249cf9Greg Clayton else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 1281331e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton } 1281431e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton return m_arm_isa != 0; 1281531e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton} 1281631e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 12817080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticebool 12818888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12819080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{ 12820888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12821888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton { 12822888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12823888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_opcode_mode = eModeThumb; 12824888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton else 12825888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton { 12826888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton AddressClass addr_class = inst_addr.GetAddressClass(); 12827080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 12828888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12829888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_opcode_mode = eModeARM; 12830888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton else if (addr_class == eAddressClassCodeAlternateISA) 12831888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_opcode_mode = eModeThumb; 12832888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton else 12833888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return false; 12834888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton } 12835888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (m_opcode_mode == eModeThumb) 12836888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12837888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton else 12838888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_opcode_cpsr = CPSR_MODE_USR; 12839888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return true; 12840888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton } 12841888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return false; 12842080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice} 1284331e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 1284464c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 1284564c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction () 1284664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 1284764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 12848b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 1284964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1285064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 1285164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 1285264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1285364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 128549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Context read_inst_context; 128559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.type = eContextReadOpcode; 128569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.SetNoArgs (); 128579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 12858b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_cpsr & MASK_CPSR_T) 1285964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 12860b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeThumb; 12861cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 1286264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1286364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1286464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 128657bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 1286664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 128677bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode16 (thumb_opcode); 1286864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1286964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 1287064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 128717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 1287264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1287364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1287464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1287564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 1287664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 12877b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeARM; 128787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 1287964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1288064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1288164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1288264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 1288364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 12884b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeInvalid; 128853063c95c54ac0303287c34f9f5af7ba7b6b8f0bcGreg Clayton m_addr = LLDB_INVALID_ADDRESS; 1288664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1288764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return success; 1288864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 1288964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 12890ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t 12891ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion () 12892ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 12893ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return m_arm_isa; 12894ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 12895ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 1289664c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 12897107e53da8bdca540db8b734ed237688eaeee85c5Greg ClaytonEmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 1289864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 12899888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton // If we are ignoring conditions, then always return true. 12900888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton // this allows us to iterate over disassembly code and still 12901888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton // emulate an instruction even if we don't have all the right 12902888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton // bits set in the CPSR register... 12903888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (m_ignore_conditions) 12904888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return true; 12905107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton 12906107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (is_conditional) 12907107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton *is_conditional = true; 1290864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 129097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton const uint32_t cond = CurrentCond (opcode); 1291064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1291164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond == UINT32_MAX) 1291264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1291364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1291464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool result = false; 1291564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton switch (UnsignedBits(cond, 3, 1)) 1291664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 12917080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice case 0: 12918080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice if (m_opcode_cpsr == 0) 12919107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12920107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12921107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12922080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice break; 12923080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice case 1: 12924107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (m_opcode_cpsr == 0) 12925107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12926107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12927107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12928080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice break; 12929080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice case 2: 12930107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (m_opcode_cpsr == 0) 12931107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12932107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12933107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12934080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice break; 12935080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice case 3: 12936107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (m_opcode_cpsr == 0) 12937107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12938107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12939107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12940080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice break; 12941080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice case 4: 12942107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (m_opcode_cpsr == 0) 12943107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12944107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12945107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12946080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice break; 1294764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 5: 12948107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (m_opcode_cpsr == 0) 12949107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12950107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12951080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice { 12952b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool n = (m_opcode_cpsr & MASK_CPSR_N); 12953b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool v = (m_opcode_cpsr & MASK_CPSR_V); 1295464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = n == v; 1295564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1295664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1295764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 6: 12958107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (m_opcode_cpsr == 0) 12959107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton result = true; 12960107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton else 12961080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice { 12962b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool n = (m_opcode_cpsr & MASK_CPSR_N); 12963b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool v = (m_opcode_cpsr & MASK_CPSR_V); 12964b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 1296564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1296664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1296764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 7: 12968107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton // Always execute (cond == 0b1110, or the special 0b1111 which gives 12969107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton // opcodes different meanings, but always means execution happpens. 12970107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton if (is_conditional) 12971107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton *is_conditional = false; 1297264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = true; 1297364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1297464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1297564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1297664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond & 1) 1297764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = !result; 1297864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return result; 1297964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 1298064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 129819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t 129827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::CurrentCond (const uint32_t opcode) 129839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 12984b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton switch (m_opcode_mode) 129859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 129869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 129879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeInvalid: 129889ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 129899ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 129909ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeARM: 129917bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return UnsignedBits(opcode, 31, 28); 129929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 129939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeThumb: 129949ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 129959ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // 'cond' field of the encoding. 129969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 129977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton const uint32_t byte_size = m_opcode.GetByteSize(); 129987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (byte_size == 2) 129997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 130007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 130017bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return Bits32(opcode, 11, 7); 130027bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 130036dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen else if (byte_size == 4) 130047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 130057bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (Bits32(opcode, 31, 27) == 0x1e && 130067bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 15, 14) == 0x02 && 130077bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 12, 12) == 0x00 && 130087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 25, 22) <= 0x0d) 130097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 130107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return Bits32(opcode, 25, 22); 130117bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 130127bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 130136dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen else 130146dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen // We have an invalid thumb instruction, let's bail out. 130156dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen break; 130167bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 130177bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return m_it_session.GetCond(); 130189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 130199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 130209ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return UINT32_MAX; // Return invalid value 130219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 130229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 130239ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 13024098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock() 13025098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 13026098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13027098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 13028098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 13029098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 13030098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock() 13031098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 13032098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13033098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 13034098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 13035b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 13036b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::BadMode (uint32_t mode) 13037b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 13038b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13039b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice switch (mode) 13040b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 13041b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 16: return false; // '10000' 13042b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 17: return false; // '10001' 13043b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 18: return false; // '10010' 13044b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 19: return false; // '10011' 13045b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 22: return false; // '10110' 13046b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 23: return false; // '10111' 13047b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 27: return false; // '11011' 13048b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 31: return false; // '11111' 13049b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice default: return true; 13050b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 13051b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 13052b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 13053b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13054b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 13055b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CurrentModeIsPrivileged () 13056b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 13057b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13058b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13059b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BadMode (mode)) 13060b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 13061b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13062b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (mode == 16) 13063888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return false; 13064b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13065b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 13066b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 13067b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13068b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticevoid 13069b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13070b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 13071b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool privileged = CurrentModeIsPrivileged(); 13072b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 1307365f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13074b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13075b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 3)) 13076b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 13077b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13078b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 13079b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13080b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 13081b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13082b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 2)) 13083b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 13084b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13085b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 13086b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13087b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 1)) 13088b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 13089b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 13090b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13091b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13092b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 13093b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13094b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 13095b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13096b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 0)) 13097b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 13098b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 13099b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13100b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 13101b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13102b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 13103b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13104b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 13105b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13106b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_cpsr = tmp_cpsr; 13107b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 13108b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13109b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 13110098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 131119ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 131129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 131139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 131149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 13115ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Check the current instruction set. 13116ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (CurrentInstrSet() == eModeARM) 131179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 13118ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 131199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 13120ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 131219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1312253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 1312353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 1312453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 131259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 131269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 131279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 131289ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 13129668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 131309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 131319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 131320f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 131330f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // we want to record it and issue a WriteRegister callback so the clients 131340f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // can track the mode changes accordingly. 131350f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen bool cpsr_changed = false; 131369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 131379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (BitIsSet(addr, 0)) 131389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 131390f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeThumb) 131400f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 131410f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeThumb); 131420f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 131430f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 131449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 13145c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISA (eModeThumb); 131469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 131479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else if (BitIsClear(addr, 1)) 131489ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 131490f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeARM) 131500f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 131510f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeARM); 131520f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 131530f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 131549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 13155c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton context.SetISA (eModeARM); 131569ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 131579ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else 131589ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; // address<1:0> == '10' => UNPREDICTABLE 131599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 131600f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (cpsr_changed) 131610f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 13162558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 131630f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen return false; 131640f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 131659ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1316653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 1316753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 1316853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 131699ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 1317064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 13171ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13172ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 13173668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13174ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 13175ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (ArchVersion() >= ARMv5T) 13176668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 13177ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 13178ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return BranchWritePC((const Context)context, addr); 13179ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 13180ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 1318126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 1318226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 13183668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 1318426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 1318526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13186668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 1318726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 1318826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return BranchWritePC((const Context)context, addr); 1318926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 1319026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 13191ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode 13192ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet () 13193ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 13194b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton return m_opcode_mode; 13195ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 13196ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 13197b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13198558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed. This function has a side effect of updating 13199558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary. 13200ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 13201ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13202ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 13203b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 13204ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen switch (arm_or_thumb) 13205ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen { 13206ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen default: 13207ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return false; 13208b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton case eModeARM: 13209ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Clear the T bit. 13210558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr &= ~MASK_CPSR_T; 13211ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 13212b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton case eModeThumb: 13213ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Set the T bit. 13214558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr |= MASK_CPSR_T; 13215ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 13216ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen } 13217ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return true; 13218ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 13219ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 13220ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for 13221ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13222ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13223ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 13224ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport() 13225ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 13226ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return (ArchVersion() >= ARMv7); 13227ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 13228ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 13229bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information 13230bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions. This status 13231bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions. 13232bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult 13233bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13234bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{ 13235bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint32_t result; 13236bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t carry_out; 13237bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t overflow; 13238bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 13239bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint64_t unsigned_sum = x + y + carry_in; 13240bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13241bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 13242bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen result = UnsignedBits(unsigned_sum, 31, 0); 132430fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice// carry_out = (result == unsigned_sum ? 0 : 1); 13244bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen overflow = ((int32_t)result == signed_sum ? 0 : 1); 132450fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice 132460fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice if (carry_in) 13247523c554292bc09fd8519379d628b5e9090acbd36Caroline Tice carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 132480fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice else 132490fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13250bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 13251bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen AddWithCarryResult res = { result, carry_out, overflow }; 13252bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen return res; 13253bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen} 13254bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 13255157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenuint32_t 13256e39f22d1a369866808b8739c3cec15063d806833Johnny ChenEmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13257157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 13258e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_kind, reg_num; 13259e39f22d1a369866808b8739c3cec15063d806833Johnny Chen switch (num) 13260157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 13261e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case SP_REG: 13262e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 13263e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 13264e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 13265e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case LR_REG: 13266e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 13267e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 13268e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 13269e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case PC_REG: 13270e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 13271e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_PC; 13272e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 13273e39f22d1a369866808b8739c3cec15063d806833Johnny Chen default: 132744fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton if (num < SP_REG) 13275e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 13276e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindDWARF; 13277e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = dwarf_r0 + num; 13278e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 13279157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 13280e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 13281e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton //assert(0 && "Invalid register number"); 13282e39f22d1a369866808b8739c3cec15063d806833Johnny Chen *success = false; 132834fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton return UINT32_MAX; 13284e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 13285e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 13286e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 13287e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 13288e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // Read our register. 13289e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13290e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 13291e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing an ARM instruction , PC reads as the address of the current 13292e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 8. 13293e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing a Thumb instruction , PC reads as the address of the current 13294e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 4. 13295e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (num == 15) 13296e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 13297e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (CurrentInstrSet() == eModeARM) 13298157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen val += 8; 13299e39f22d1a369866808b8739c3cec15063d806833Johnny Chen else 13300e39f22d1a369866808b8739c3cec15063d806833Johnny Chen val += 4; 13301157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 13302157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 13303157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return val; 13304157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 13305157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 13306ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the 13307ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result. 13308ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 13309ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 13310ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual: 13311ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 13312ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then // Can only occur for encoding A1 13313ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ALUWritePC(result); // setflags is always FALSE here 13314ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else 13315ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// R[d] = result; 13316ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if setflags then 13317ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.N = result<31>; 13318ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.Z = IsZeroBit(result); 13319ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.C = carry; 13320ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// // APSR.V unchanged 13321ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 13322ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which 13323ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u. 13324ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool 1332510530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 1332610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 1332710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t Rd, 1332810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen bool setflags, 1332910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 1333010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 13331ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{ 13332ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (Rd == 15) 13333ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 13334ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (!ALUWritePC (context, result)) 13335ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 13336ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 13337ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen else 13338ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 13339a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t reg_kind, reg_num; 13340a695f958db37c102d480a9c0780abec262ba8332Johnny Chen switch (Rd) 13341a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 13342a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case SP_REG: 13343a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindGeneric; 13344a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 13345a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 13346a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case LR_REG: 13347a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindGeneric; 13348a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 13349a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 13350a695f958db37c102d480a9c0780abec262ba8332Johnny Chen default: 13351a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindDWARF; 13352a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = dwarf_r0 + Rd; 13353a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 13354a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13355ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 13356ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (setflags) 1335710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return WriteFlags (context, result, carry, overflow); 1335810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen } 1335910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return true; 1336010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen} 1336110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 1336210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 1336310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual: 1336410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 1336510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>; 1336610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result); 1336710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry; 1336810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow 1336910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 1337010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means 1337110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags. 1337210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool 1337310530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context, 1337410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 1337510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 1337610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 1337710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{ 13378b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 1337924348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 1338024348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1338110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (carry != ~0u) 1338224348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 1338310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (overflow != ~0u) 1338424348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13385b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_new_inst_cpsr != m_opcode_cpsr) 1338610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen { 1338710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1338810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 13389ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 13390ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return true; 13391ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen} 13392ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 1339364c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 13394888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 1339564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 13396c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // Advance the ITSTATE bits to their values for the next instruction. 13397b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13398c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.ITAdvance(); 13399c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 13400888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton ARMOpcode *opcode_data = NULL; 13401080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 13402080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice if (m_opcode_mode == eModeThumb) 13403888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13404080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice else if (m_opcode_mode == eModeARM) 13405888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13406080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 13407888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (opcode_data == NULL) 13408080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice return false; 13409080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 13410888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13411888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13412888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 13413888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton bool success = false; 13414888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13415080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice { 13416888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13417061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton dwarf_cpsr, 13418061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton 0, 13419061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton &success); 13420080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice } 13421888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 13422888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton // Only return false if we are unable to read the CPSR if we care about conditions 13423888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (success == false && m_ignore_conditions == false) 13424888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return false; 13425080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice 13426888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton uint32_t orig_pc_value = 0; 13427888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (auto_advance_pc) 134280fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice { 13429888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13430888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (!success) 13431888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return false; 134320fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice } 134330fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice 13434888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton // Call the Emulate... function. 13435888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 134360fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice if (!success) 134370fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice return false; 134380fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice 13439888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (auto_advance_pc) 134400fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice { 13441888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13442888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (!success) 134430fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice return false; 134440fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice 13445888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13446888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton { 13447888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (opcode_data->size == eSize32) 13448888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton after_pc_value += 4; 13449888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton else if (opcode_data->size == eSize16) 13450888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton after_pc_value += 2; 13451888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 13452888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton EmulateInstruction::Context context; 13453888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton context.type = eContextAdvancePC; 13454888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton context.SetNoArgs(); 13455888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13456888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return false; 13457888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 13458888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton } 134590fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice } 134600fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice return true; 1346164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 134626b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 134636b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Ticebool 13464dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline TiceEmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 134656b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice{ 13466dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if (!test_data) 134676b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13468dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Missing test data.\n"); 134696b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 134706b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 13471dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice 13472dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice static ConstString opcode_key ("opcode"); 13473dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice static ConstString before_key ("before_state"); 13474dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice static ConstString after_key ("after_state"); 13475dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice 13476dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 134776b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 134786b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice uint32_t test_opcode; 13479dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 134806b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13481dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 134826b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 134836b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 13484dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice test_opcode = value_sp->GetUInt64Value (); 134856b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 134866b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice if (arch.GetTriple().getArch() == llvm::Triple::arm) 134876b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 134886b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice m_opcode_mode = eModeARM; 134896b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice m_opcode.SetOpcode32 (test_opcode); 134906b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 134916b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 134926b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 134936b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice m_opcode_mode = eModeThumb; 134946b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice if (test_opcode < 0x10000) 134956b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice m_opcode.SetOpcode16 (test_opcode); 134966b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice else 134976b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice m_opcode.SetOpcode32 (test_opcode); 134986b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 134996b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 135006b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice else 135016b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13502dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Invalid arch.\n"); 135036b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 135046b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 135056b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 135066b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice EmulationStateARM before_state; 135076b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice EmulationStateARM after_state; 135086b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 13509dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice value_sp = test_data->GetValueForKey (before_key); 13510dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 135116b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13512dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 135136b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 135146b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 13515dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice 1351657b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13517dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if (!before_state.LoadStateFromDictionary (state_dictionary)) 135186b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13519dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 135206b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 135216b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 135226b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 13523dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice value_sp = test_data->GetValueForKey (after_key); 13524dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 135256b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13526dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13527dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice return false; 135286b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 13529dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice 1353057b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton state_dictionary = value_sp->GetAsDictionary (); 13531dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if (!after_state.LoadStateFromDictionary (state_dictionary)) 135326b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13533dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 135346b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 135356b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 13536dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice 135376b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice SetBaton ((void *) &before_state); 135386b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 135396b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice &EmulationStateARM::WritePseudoMemory, 135406b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice &EmulationStateARM::ReadPseudoRegister, 135416b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice &EmulationStateARM::WritePseudoRegister); 135426b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 13543888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 135446b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice if (!success) 135456b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice { 13546dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 135476b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return false; 135486b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice } 135496b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice 135506b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice success = before_state.CompareState (after_state); 13551dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice if (!success) 13552dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13553dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice 135546b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice return success; 135556b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice} 13556c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// 13557c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// 13558c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//const char * 13559c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13560c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//{ 13561c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// if (reg_kind == eRegisterKindGeneric) 13562c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// { 13563c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// switch (reg_num) 13564c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// { 13565c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// case LLDB_REGNUM_GENERIC_PC: return "pc"; 13566c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// case LLDB_REGNUM_GENERIC_SP: return "sp"; 13567c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// case LLDB_REGNUM_GENERIC_FP: return "fp"; 13568c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// case LLDB_REGNUM_GENERIC_RA: return "lr"; 13569c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13570c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// default: return NULL; 13571c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// } 13572c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// } 13573c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// else if (reg_kind == eRegisterKindDWARF) 13574c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// { 13575c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// return GetARMDWARFRegisterName (reg_num); 13576c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// } 13577c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// return NULL; 13578c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//} 13579c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton// 13580c07d451bb046e47215bd73fda0235362cc6b1a47Greg Claytonbool 13581c07d451bb046e47215bd73fda0235362cc6b1a47Greg ClaytonEmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13582888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{ 1358375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton unwind_plan.Clear(); 13584c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13585c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 1358668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda UnwindPlan::RowSP row(new UnwindPlan::Row); 13587c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13588c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton // Our previous Call Frame Address is the stack pointer 1358968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFARegister (dwarf_sp); 13590c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13591c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton // Our previous PC is in the LR 1359268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13593c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton unwind_plan.AppendRow (row); 13594c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13595c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton // All other registers are the same. 13596c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13597c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton unwind_plan.SetSourceName ("EmulateInstructionARM"); 13598c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton return true; 13599888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton} 13600888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 13601c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13602c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13603c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton 13604