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