EmulateInstructionARM.cpp revision 688926f8fb9a56964249ec970b4ae313a5b366d4
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 26e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// Convenient macro definitions. 27e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#define APSR_C Bit32(m_inst_cpsr, CPSR_C) 28e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#define APSR_V Bit32(m_inst_cpsr, CPSR_V) 29e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 30f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 31f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 320e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 330e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 340e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// ITSession implementation 350e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 360e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen 38930704795c783e5bf1768a43da6f957108b40873Johnny Chen// A8.6.50 39930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 40930704795c783e5bf1768a43da6f957108b40873Johnny Chenstatic unsigned short CountITSize(unsigned ITMask) { 41930704795c783e5bf1768a43da6f957108b40873Johnny Chen // First count the trailing zeros of the IT mask. 42930704795c783e5bf1768a43da6f957108b40873Johnny Chen unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 43930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (TZ > 3) 44930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 45930704795c783e5bf1768a43da6f957108b40873Johnny Chen printf("Encoding error: IT Mask '0000'\n"); 46930704795c783e5bf1768a43da6f957108b40873Johnny Chen return 0; 47930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 48930704795c783e5bf1768a43da6f957108b40873Johnny Chen return (4 - TZ); 49930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 50930704795c783e5bf1768a43da6f957108b40873Johnny Chen 51930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Init ITState. Note that at least one bit is always 1 in mask. 52930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InitIT(unsigned short bits7_0) 53930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 54930704795c783e5bf1768a43da6f957108b40873Johnny Chen ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 55930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (ITCounter == 0) 56930704795c783e5bf1768a43da6f957108b40873Johnny Chen return false; 57930704795c783e5bf1768a43da6f957108b40873Johnny Chen 58930704795c783e5bf1768a43da6f957108b40873Johnny Chen // A8.6.50 IT 59930704795c783e5bf1768a43da6f957108b40873Johnny Chen unsigned short FirstCond = Bits32(bits7_0, 7, 4); 60930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (FirstCond == 0xF) 61930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 62930704795c783e5bf1768a43da6f957108b40873Johnny Chen printf("Encoding error: IT FirstCond '1111'\n"); 63930704795c783e5bf1768a43da6f957108b40873Johnny Chen return false; 64930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 65930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (FirstCond == 0xE && ITCounter != 1) 66930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 67930704795c783e5bf1768a43da6f957108b40873Johnny Chen printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 68930704795c783e5bf1768a43da6f957108b40873Johnny Chen return false; 69930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 70930704795c783e5bf1768a43da6f957108b40873Johnny Chen 71930704795c783e5bf1768a43da6f957108b40873Johnny Chen ITState = bits7_0; 72930704795c783e5bf1768a43da6f957108b40873Johnny Chen return true; 73930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 74930704795c783e5bf1768a43da6f957108b40873Johnny Chen 75930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Update ITState if necessary. 76930704795c783e5bf1768a43da6f957108b40873Johnny Chenvoid ITSession::ITAdvance() 77930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 78930704795c783e5bf1768a43da6f957108b40873Johnny Chen assert(ITCounter); 79930704795c783e5bf1768a43da6f957108b40873Johnny Chen --ITCounter; 80930704795c783e5bf1768a43da6f957108b40873Johnny Chen if (ITCounter == 0) 81930704795c783e5bf1768a43da6f957108b40873Johnny Chen ITState = 0; 82930704795c783e5bf1768a43da6f957108b40873Johnny Chen else 83930704795c783e5bf1768a43da6f957108b40873Johnny Chen { 84930704795c783e5bf1768a43da6f957108b40873Johnny Chen unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 85930704795c783e5bf1768a43da6f957108b40873Johnny Chen SetBits32(ITState, 4, 0, NewITState4_0); 86930704795c783e5bf1768a43da6f957108b40873Johnny Chen } 87930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 88930704795c783e5bf1768a43da6f957108b40873Johnny Chen 89930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Return true if we're inside an IT Block. 90930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InITBlock() 91930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 92930704795c783e5bf1768a43da6f957108b40873Johnny Chen return ITCounter != 0; 93930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 94930704795c783e5bf1768a43da6f957108b40873Johnny Chen 95c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// Return true if we're the last instruction inside an IT Block. 96c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool ITSession::LastInITBlock() 97c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{ 98c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return ITCounter == 1; 99c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen} 100c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 101930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Get condition bits for the current thumb instruction. 102930704795c783e5bf1768a43da6f957108b40873Johnny Chenuint32_t ITSession::GetCond() 103930704795c783e5bf1768a43da6f957108b40873Johnny Chen{ 104c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen if (InITBlock()) 105c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return Bits32(ITState, 7, 4); 106c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen else 107c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return COND_AL; 108930704795c783e5bf1768a43da6f957108b40873Johnny Chen} 109930704795c783e5bf1768a43da6f957108b40873Johnny Chen 11064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// ARM constants used during decoding 11164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define REG_RD 0 11264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define LDM_REGLIST 1 113e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define SP_REG 13 114e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define LR_REG 14 11564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REG 15 11664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REGLIST_BIT 0x8000 11764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 118251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv4 (1u << 0) 11964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv4T (1u << 1) 12064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5T (1u << 2) 12164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TE (1u << 3) 12264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TEJ (1u << 4) 123251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv6 (1u << 5) 12464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6K (1u << 6) 12564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6T2 (1u << 7) 126251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv7 (1u << 8) 12760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen#define ARMv8 (1u << 9) 12864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMvAll (0xffffffffu) 12964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 1319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 1329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 1332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 1340e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1350e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1360e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation 1370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1380e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1390e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen 1402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize () 1427dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{ 1432b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen 1452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate () 14764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 1482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 150fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 151fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 152fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 153fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 1549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 1569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 157fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 158fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t random_data = rand (); 159fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 160fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 161cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address, random_data, addr_byte_size)) 162fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 163fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 164fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 165fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 166fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 167713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 168713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 169713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n) 170713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 1719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 1739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 174713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 17562ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen bool success; 176713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 177713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 178713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 179713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 180713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 181713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 182713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 183713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 184713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 185713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 186713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 18708c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to 18808c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates 18908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data. 1902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1919f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulatePUSH (ARMEncoding encoding) 19264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 19364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0 19464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton // ARM pseudo code... 19564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (ConditionPassed()) 19664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 19764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton EncodingSpecificOperations(); 19864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton NullCheckIfThumbEE(13); 19964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = SP - 4*BitCount(registers); 20064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 20164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i = 0 to 14) 20264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 20364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (registers<i> == ’1’) 20464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 20564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 20664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = bits(32) UNKNOWN; 20764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 20864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = R[i]; 20964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = address + 4; 21064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 21364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (registers<15> == ’1’) // Only possible for encoding A1 or A2 21464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = PCStoreValue(); 21564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 21664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton SP = SP - 4*BitCount(registers); 21764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif 21964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 22064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 2212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 22264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 22364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 22464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 22664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 228e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 22964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 23064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 2313c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen uint32_t registers = 0; 23291d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 2333c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen switch (encoding) { 234aedde1c6a33b123031499800f56954adc86058f5Johnny Chen case eEncodingT1: 235108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 7, 0); 236aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // The M bit represents LR. 237bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 238ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 14); 239aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 240aedde1c6a33b123031499800f56954adc86058f5Johnny Chen if (BitCount(registers) < 1) 241aedde1c6a33b123031499800f56954adc86058f5Johnny Chen return false; 242aedde1c6a33b123031499800f56954adc86058f5Johnny Chen break; 2437dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT2: 2447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // Ignore bits 15 & 13. 245108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0) & ~0xa000; 2467dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BitCount(registers) < 2 then UNPREDICTABLE; 2477dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen if (BitCount(registers) < 2) 2487dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 2497dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 2507dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT3: 251108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 2527dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BadReg(t) then UNPREDICTABLE; 25391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (BadReg(Rt)) 2547dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 25591d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 2567dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 2573c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA1: 258108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0); 259a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // Instead of return false, let's handle the following case as well, 260a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // which amounts to pushing one reg onto the full descending stacks. 261a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 2623c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 2633c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA2: 264108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 2657dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if t == 13 then UNPREDICTABLE; 26691d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt == dwarf_sp) 2673c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen return false; 26891d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 2693c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 270ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 271ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 2723c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen } 273ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 27464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t addr = sp - sp_offset; 27564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton uint32_t i; 27664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 2799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 2809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 28164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i=0; i<15; ++i) 28264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2837c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 28464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_r0 + i; 2869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 287e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(i, &success); 28864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 28964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 290cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 29164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 29264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr += addr_byte_size; 29364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 29464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 29564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2967c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 29764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_pc; 2999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 300e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 30164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 30264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 303e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (!MemAWrite (context, addr, pc, addr_byte_size)) 30464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 30564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 30664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 30764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton context.type = EmulateInstruction::eContextAdjustStackPointer; 3089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 30964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 3102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 31164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 31264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 31364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return true; 31464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 31564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 316ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from 317ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates 318ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data. 3192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 3209f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulatePOP (ARMEncoding encoding) 321ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{ 322ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0 323ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // ARM pseudo code... 324ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (ConditionPassed()) 325ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 326ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(13); 327ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen address = SP; 328ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for i = 0 to 14 329ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if registers<i> == ‘1’ then 330ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 331ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if registers<15> == ‘1’ then 332ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if UnalignedAllowed then 333ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemU[address,4]); 334ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen else 335ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemA[address,4]); 336ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 337ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 338ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 339ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif 340ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 341ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen bool success = false; 3422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 343ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 344ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 345ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 3462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 347ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 3482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 349e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 350ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 351ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 352ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t registers = 0; 353ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t Rt; // the destination register 354ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen switch (encoding) { 355ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT1: 356ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 7, 0); 357ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // The P bit represents PC. 358bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 359ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 15); 360ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 361ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (BitCount(registers) < 1) 362ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 363ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 364ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT2: 365ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Ignore bit 13. 366ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0) & ~0x2000; 367ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 368bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 369ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 370098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 371098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 372098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 373ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 374ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT3: 375ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 376ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 377098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 13) 378098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 379098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 380ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 381ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 382ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 383ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA1: 384ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0); 385ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Instead of return false, let's handle the following case as well, 386ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // which amounts to popping one reg from the full descending stacks. 387ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 388ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 389ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 390098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 391ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 392ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 393ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA2: 394ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 395ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 then UNPREDICTABLE; 396ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (Rt == dwarf_sp) 397ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 398ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 399ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 400ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen default: 401ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 402ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 403ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 404ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t addr = sp; 405ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t i, data; 406ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 4089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 4099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 4109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 411ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for (i=0; i<15; ++i) 412ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 4137c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 414ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 4159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_r0 + i; 4169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 417cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, 4, 0, &success); 418ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 419ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 4209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 421ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 422ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr += addr_byte_size; 423ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 424ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 425ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4267c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 427ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 4289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_pc; 4299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 430cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, 4, 0, &success); 431ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 432ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 433f3eaacfc02d0a98d3bac1eaef74ad5c1c66ccfdcJohnny Chen // In ARMv5T and above, this is an interworking branch. 434668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 435ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 436ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr += addr_byte_size; 437ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 438ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 439ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 4409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 441ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 443ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 444ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 445ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return true; 446ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen} 447ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4485b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// Set r7 or ip to point to saved value residing within the stack. 449bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen// ADD (SP plus immediate) 4502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 4519f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateADDRdSPImm (ARMEncoding encoding) 452bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{ 453bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0 454bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen // ARM pseudo code... 455bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (ConditionPassed()) 456bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 457bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen EncodingSpecificOperations(); 458bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 459bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if d == 15 then 460bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 461bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen else 462bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen R[d] = result; 463bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if setflags then 464bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.N = result<31>; 465bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.Z = IsZeroBit(result); 466bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.C = carry; 467bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.V = overflow; 468bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 469bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#endif 470bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 471bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen bool success = false; 4722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 473bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (!success) 474bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 475bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 4762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 477bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 478e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 479bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (!success) 480bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 481bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t Rd; // the destination register 482bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t imm32; 483bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen switch (encoding) { 484bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingT1: 485bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = 7; 486bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 487bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 488bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingA1: 489bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = Bits32(opcode, 15, 12); 490bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 491bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 492bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen default: 493bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 494bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 495bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t sp_offset = imm32; 496bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t addr = sp + sp_offset; // a pointer to the stack area 497bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 4989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 4999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 5009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register sp_reg; 5019bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 5029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, sp_offset); 503bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 5042b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 505bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 506bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 507bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return true; 508bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen} 509bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 5102ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer. 5112ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register) 5122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5139f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdSP (ARMEncoding encoding) 5142ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{ 5152ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0 5162ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // ARM pseudo code... 5172ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (ConditionPassed()) 5182ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 5192ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen EncodingSpecificOperations(); 5202ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen result = R[m]; 5212ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if d == 15 then 5222ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5232ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen else 5242ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen R[d] = result; 5252ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if setflags then 5262ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.N = result<31>; 5272ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.Z = IsZeroBit(result); 5282ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.C unchanged 5292ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.V unchanged 5302ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5312ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif 5322ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5332ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen bool success = false; 5342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //const uint32_t opcode = OpcodeAsUnsigned (&success); 5351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen //if (!success) 5361c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // return false; 5372ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 5392ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 540e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 5412ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (!success) 5422ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5432ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen uint32_t Rd; // the destination register 5442ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen switch (encoding) { 5452ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingT1: 5462ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 7; 5472ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 5482ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingA1: 5492ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 12; 5502ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 5512ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen default: 5522ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5532ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 5559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 5569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 5579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register sp_reg; 5589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 5599bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, 0); 5602ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 5622ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5632ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5642ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return true; 5652ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen} 5662ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5671c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7). 5681c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register) 5692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVLowHigh (ARMEncoding encoding) 5711c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{ 5729f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen return EmulateMOVRdRm (encoding); 573338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen} 574338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen 575338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register. 576338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register) 577338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool 5789f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdRm (ARMEncoding encoding) 579338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{ 5801c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0 5811c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // ARM pseudo code... 5821c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (ConditionPassed()) 5831c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 5841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen EncodingSpecificOperations(); 5851c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen result = R[m]; 5861c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if d == 15 then 5871c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5881c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen else 5891c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen R[d] = result; 5901c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if setflags then 5911c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.N = result<31>; 5921c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.Z = IsZeroBit(result); 5931c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.C unchanged 5941c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.V unchanged 5951c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 5961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif 5971c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 5981c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen bool success = false; 5992b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 6001c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (!success) 6011c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6021c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 6032b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 6041c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 6051c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rm; // the source register 6061c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rd; // the destination register 607338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen bool setflags; 6081c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen switch (encoding) { 6091c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen case eEncodingT1: 6107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 6111c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen Rm = Bits32(opcode, 6, 3); 612338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = false; 6137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 6147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 615338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen break; 616338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen case eEncodingT2: 6177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 2, 0); 618338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen Rm = Bits32(opcode, 5, 3); 619338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = true; 6207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (InITBlock()) 6217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6221c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen break; 6237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT3: 6247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 6257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 6267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 6277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 6287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (setflags && (BadReg(Rd) || BadReg(Rm))) 6297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 6317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 6327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6331c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen default: 6341c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 6367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = ReadCoreReg(Rm, &success); 6371c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (!success) 6381c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6391c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 6401c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // The context specifies that Rm is to be moved into Rd. 6419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 6429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 6439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 6449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 6459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, 0); 646ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 64710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 648ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 6491c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 6501c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return true; 6511c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen} 6521c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 653357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register. It 654357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value. 655357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate) 656357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool 6579f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdImm (ARMEncoding encoding) 658357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{ 659357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0 660357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // ARM pseudo code... 661357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if (ConditionPassed()) 662357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 663357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen EncodingSpecificOperations(); 664357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen result = imm32; 665357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if d == 15 then // Can only occur for ARM encoding 666357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen ALUWritePC(result); // setflags is always FALSE here 667357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen else 668357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen R[d] = result; 669357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if setflags then 670357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.N = result<31>; 671357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.Z = IsZeroBit(result); 672357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.C = carry; 673357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // APSR.V unchanged 674357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 675357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif 676357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen bool success = false; 677357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 678357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if (!success) 679357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen return false; 680357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 681357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if (ConditionPassed()) 682357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 683357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t Rd; // the destination register 684357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the immediate value to be written to Rd 685357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 686357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen bool setflags; 687357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen switch (encoding) { 688357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen case eEncodingT1: 6897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 10, 8); 690357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen setflags = !InITBlock(); 691357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 692e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen carry = APSR_C; 693357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen break; 694357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen case eEncodingT2: 6957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 696357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen setflags = BitIsSet(opcode, 20); 6977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 6989798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen if (BadReg(Rd)) 6999798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen return false; 700357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen break; 701357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen default: 702357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen return false; 703357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 704357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t result = imm32; 705357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 706357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // The context specifies that an immediate is to be moved into Rd. 7079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 7089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 7099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 710ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 71110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 712ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 713357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 714357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen return true; 715357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen} 716357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 717d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 718d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the value. 71928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool 720d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny ChenEmulateInstructionARM::EmulateMVNImm (ARMEncoding encoding) 72128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{ 72228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0 72328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // ARM pseudo code... 72428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if (ConditionPassed()) 72528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen { 72628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen EncodingSpecificOperations(); 72728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen result = NOT(imm32); 72828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if d == 15 then // Can only occur for ARM encoding 72928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 73028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen else 73128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen R[d] = result; 73228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if setflags then 73328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.N = result<31>; 73428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.Z = IsZeroBit(result); 73528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.C = carry; 73628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // APSR.V unchanged 73728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen } 73828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif 73933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen bool success = false; 74033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 74133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen if (!success) 74233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return false; 74333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 74433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen if (ConditionPassed()) 74533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen { 74633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t Rd; // the destination register 747357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 748357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 74933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen bool setflags; 75033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen switch (encoding) { 75133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingT1: 75233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 11, 8); 75333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 754d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 75533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 75633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingA1: 75733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 15, 12); 75833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 759d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 760d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 761d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 762d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (Rd == 15 && setflags) 763d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 76433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 76533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen default: 76633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return false; 76733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 76833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t result = ~imm32; 76933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 77033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen // The context specifies that an immediate is to be moved into Rd. 7719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 7729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 7739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 774ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 77510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 776ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 77733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 77833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return true; 77928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen} 78028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 781d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 782d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the result. 783d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chenbool 784d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny ChenEmulateInstructionARM::EmulateMVNReg (ARMEncoding encoding) 785d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen{ 786d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#if 0 787d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // ARM pseudo code... 788d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (ConditionPassed()) 789d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 790d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EncodingSpecificOperations(); 791d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 792d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen result = NOT(shifted); 793d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if d == 15 then // Can only occur for ARM encoding 794d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ALUWritePC(result); // setflags is always FALSE here 795d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen else 796d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen R[d] = result; 797d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if setflags then 798d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.N = result<31>; 799d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.Z = IsZeroBit(result); 800d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.C = carry; 801d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // APSR.V unchanged 802d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 803d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#endif 804d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 805d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen bool success = false; 806d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 807d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!success) 808d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 809d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 810d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (ConditionPassed()) 811d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 812d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rm; // the source register 813d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rd; // the destination register 814d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ARM_ShifterType shift_t; 815d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 816d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen bool setflags; 817d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t carry; // the carry bit after the shift operation 818d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen switch (encoding) { 819d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT1: 820d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 2, 0); 821d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 5, 3); 822d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = !InITBlock(); 823d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_t = SRType_LSL; 824d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_n = 0; 825d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (InITBlock()) 826d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 827d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 828d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT2: 829d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 11, 8); 830d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 831d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 832d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 833d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 834d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if ((BadReg(Rd) || BadReg(Rm))) 835d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 836d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingA1: 837d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 15, 12); 838d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 839d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 840d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 841d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 842d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen default: 843d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 844d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 845d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t value = ReadCoreReg(Rm, &success); 846d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!success) 847d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 848d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 849d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry); 850d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t result = ~shifted; 851d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 852d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // The context specifies that an immediate is to be moved into Rd. 853d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EmulateInstruction::Context context; 854d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.type = EmulateInstruction::eContextImmediate; 855d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.SetNoArgs (); 856d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 857d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 858d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 859d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 860d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return true; 861d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen} 862d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 863788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register). 864788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal) 8652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 866c9de910d61f0471d18fced716fc10681ef432010Johnny ChenEmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding) 867788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{ 868788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0 869788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen // ARM pseudo code... 870788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (ConditionPassed()) 871788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 872788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 873788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen base = Align(PC,4); 874788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen address = if add then (base + imm32) else (base - imm32); 875788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen data = MemU[address,4]; 876788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if t == 15 then 877788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 878788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen elsif UnalignedSupport() || address<1:0> = ‘00’ then 879788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = data; 880788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else // Can only apply before ARMv7 881788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 882788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = ROR(data, 8*UInt(address<1:0>)); 883788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else 884788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = bits(32) UNKNOWN; 885788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 886788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif 887788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 888788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen bool success = false; 8892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 890788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 891788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 892788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 8932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 894788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 895e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 896788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 897788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 898809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen 899809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen // PC relative immediate load context 9009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 9019bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 9029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register pc_reg; 9039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 9049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 0); 9059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 906c9de910d61f0471d18fced716fc10681ef432010Johnny Chen uint32_t Rt; // the destination register 907788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t imm32; // immediate offset from the PC 908c9de910d61f0471d18fced716fc10681ef432010Johnny Chen bool add; // +imm32 or -imm32? 909c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t base; // the base address 910c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t address; // the PC relative address 911788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t data; // the literal data value from the PC relative load 912788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen switch (encoding) { 913788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen case eEncodingT1: 914c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 10, 8); 915788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 916c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = true; 917c9de910d61f0471d18fced716fc10681ef432010Johnny Chen break; 918c9de910d61f0471d18fced716fc10681ef432010Johnny Chen case eEncodingT2: 919c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 15, 12); 920c9de910d61f0471d18fced716fc10681ef432010Johnny Chen imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 921c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = BitIsSet(opcode, 23); 922098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 923c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 924788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen break; 925788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen default: 926788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 927788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 928c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 929e39f22d1a369866808b8739c3cec15063d806833Johnny Chen base = Align(pc, 4); 930c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (add) 931c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base + imm32; 932c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 933c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base - imm32; 934e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 935e39f22d1a369866808b8739c3cec15063d806833Johnny Chen context.SetRegisterPlusOffset(pc_reg, address - base); 936cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 937788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 938809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen return false; 939c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 940c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Rt == 15) 941c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 942c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Bits32(address, 1, 0) == 0) 943c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 944c9de910d61f0471d18fced716fc10681ef432010Johnny Chen // In ARMv5T and above, this is an interworking branch. 945668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 946c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 947c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 948c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 949c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 950c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 951c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 952c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 953c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 954c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 955c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 956c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else // We don't handle ARM for now. 957c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 958c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 959c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 960788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 961788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 962788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return true; 963788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen} 964788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 9655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP. 966fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate) 9672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 968864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateADDSPImm (ARMEncoding encoding) 969fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{ 970fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0 971fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen // ARM pseudo code... 972fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (ConditionPassed()) 973fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 974fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen EncodingSpecificOperations(); 975fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 976fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if d == 15 then // Can only occur for ARM encoding 977fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 978fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen else 979fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen R[d] = result; 980fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if setflags then 981fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.N = result<31>; 982fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.Z = IsZeroBit(result); 983fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.C = carry; 984fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.V = overflow; 985fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 986fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif 987fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 988fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen bool success = false; 9892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 990fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (!success) 991fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 992fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 9932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 994fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 995e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 996fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (!success) 997fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 998fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen uint32_t imm32; // the immediate operand 999fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen switch (encoding) { 1000fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen case eEncodingT2: 1001fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1002fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen break; 1003fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen default: 1004fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 1005fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1006fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t sp_offset = imm32; 1007fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1008fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 10099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 10109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 10119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 1012fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 10132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1014fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 1015fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1016fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return true; 1017fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen} 1018fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1019fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP. 10205b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register) 10212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1022864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateADDSPRm (ARMEncoding encoding) 10235b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{ 10245b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0 10255b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen // ARM pseudo code... 10265b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (ConditionPassed()) 10275b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 10285b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen EncodingSpecificOperations(); 10295b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10305b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 10315b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if d == 15 then 10325b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen ALUWritePC(result); // setflags is always FALSE here 10335b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen else 10345b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen R[d] = result; 10355b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if setflags then 10365b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.N = result<31>; 10375b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.Z = IsZeroBit(result); 10385b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.C = carry; 10395b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.V = overflow; 10405b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 10415b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif 10425b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 10435b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen bool success = false; 10442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 10455b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 10465b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 10475b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 10482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 10495b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 1050e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 10515b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 10525b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 10535b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen uint32_t Rm; // the second operand 10545b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen switch (encoding) { 10555b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen case eEncodingT2: 10565b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen Rm = Bits32(opcode, 6, 3); 10575b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen break; 10585b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen default: 10595b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 10605b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 1061e39f22d1a369866808b8739c3cec15063d806833Johnny Chen int32_t reg_value = ReadCoreReg(Rm, &success); 10625b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 10635b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 10645b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 10655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 10665b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 10679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 10689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 10699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (reg_value); 10705b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 10712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 10725b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 10735b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 10745b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return true; 10755b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen} 10765b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 10779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 10789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or 10799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM. 10809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate) 10819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 10829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny ChenEmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 10839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 10849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 10859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 10869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 10879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 10889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 10899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 10909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC - 4; 10919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 10929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC<31:1> : '1'; 10939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if targetInstrSet == InstrSet_ARM then 10949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = Align(PC,4) + imm32; 10959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 10969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = PC + imm32; 10979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen SelectInstrSet(targetInstrSet); 10989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BranchWritePC(targetAddress); 10999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 11009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 11019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 11029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen bool success = false; 11039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 11049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 11059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 11069b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 11079b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 11089b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 11099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 11109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1111e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 11129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 11139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 111453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t lr; // next instruction address 111553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 11169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen int32_t imm32; // PC-relative offset 11179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 1118d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen case eEncodingT1: 1119d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 1120e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1121bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 1122d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 1123bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1124bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 1125d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 1126d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I1 = !(J1 ^ S); 1127d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I2 = !(J2 ^ S); 112853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1129d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1130e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 11319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1132098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1133ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1134d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen break; 1135d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen } 11369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT2: 11379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 1138e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1139bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 11409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10H = Bits32(opcode, 25, 16); 1141bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1142bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 11439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10L = Bits32(opcode, 10, 1); 11449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I1 = !(J1 ^ S); 11459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I2 = !(J2 ^ S); 114653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 11479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1148e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 11499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1150098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1151ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 11529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 11539b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1154c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen case eEncodingA1: 1155c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen lr = pc + 4; // return address 1156c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1157e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 11589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1159c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen break; 11609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA2: 11619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen lr = pc + 4; // return address 11629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1163e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 11649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 11659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 11669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 11679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 11689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 11699b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 11709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 11719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 11729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 11739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 11749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 11759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 11769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 11779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and 11789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register. 11799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register) 11809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 11819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny ChenEmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 11829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 11839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 11849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 11859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 11869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 11879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 11889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen target = R[m]; 11899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 11909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 4; 11919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = next_instr_addr; 11929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 11939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 2; 11949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = next_instr_addr<31:1> : ‘1’; 11959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BXWritePC(target); 11969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 11979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 11989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 11999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen bool success = false; 12009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 12019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 12029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 12039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 12049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 12059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 12069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1208e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 12099b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen addr_t lr; // next instruction address 12109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 12119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 12129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t Rm; // the register with the target address 12139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 12149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT1: 1215e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = (pc - 2) | 1u; // return address 12169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 6, 3); 12179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 12189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 12199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1220098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1221ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 12229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 12239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA1: 1224e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc - 4; // return address 12259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 3, 0); 12269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 12279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 12289b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1229b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 12309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 12319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 12329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1233e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1234ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1235ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 12369bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 12379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 12389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegister (dwarf_reg); 12399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 12409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1241668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 12429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 12439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 12449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 12459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 12469b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 1247ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1248ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// BX 1249ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool 1250ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny ChenEmulateInstructionARM::EmulateBXRm (ARMEncoding encoding) 1251ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{ 1252ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0 1253ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // ARM pseudo code... 1254ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (ConditionPassed()) 1255ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 1256ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen EncodingSpecificOperations(); 1257ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen BXWritePC(R[m]); 1258ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1259ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif 1260ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 1261ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen bool success = false; 1262ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 1263ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1264ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1265ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 1266ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (ConditionPassed()) 1267ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 12689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1270ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen uint32_t Rm; // the register with the target address 1271ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen switch (encoding) { 1272ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingT1: 1273ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 6, 3); 1274098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1275ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1276ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1277ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingA1: 1278ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 3, 0); 1279ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1280ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen default: 1281ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1282ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1283e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1284ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1285ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 12869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 12879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 12889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1289668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetRegister (dwarf_reg); 1290668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 1291ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1292ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1293ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return true; 1294ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen} 1295ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 12960d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset. 12970d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate) 12982b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1299864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateSUBR7IPImm (ARMEncoding encoding) 13000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 13010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 13020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 13030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 13040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 13050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 13060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 13070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 13080d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 13090d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 13100d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 13110d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 13120d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 13130d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 13140d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 13150d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 13160d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 13170d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 13180d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13190d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen bool success = false; 13202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 13210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 13220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13230d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 13250d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 1326e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t ip = ReadCoreReg (12, &success); 13270d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 13280d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13290d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 13300d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 13310d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 13320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 13330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 13340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 13350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 13370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t ip_offset = imm32; 13380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = ip - ip_offset; // the adjusted ip value 13390d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 13419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 13429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 13439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 13449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 13450d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 13470d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 13490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 13500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 13510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset. 13530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate) 13542b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1355864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateSUBIPSPImm (ARMEncoding encoding) 13560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 13570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 13580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 13590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 13600d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 13610d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 13620d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 13630d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 13640d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 13650d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 13660d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 13670d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 13680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 13690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 13700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 13710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 13720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 13730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 13740d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13750d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen bool success = false; 13762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 13770d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 13780d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13790d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 13810d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 1382e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 13830d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 13840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 13860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 13870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 13880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 13890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 13900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 13910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 13920d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 13930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t sp_offset = imm32; 13940d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = sp - sp_offset; // the adjusted stack pointer value 13950d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 13969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 13979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 13989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 13999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 14009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 14010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 14022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 14030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 14040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 14050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 14060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 14070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 14084c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen// A sub operation to adjust the SP -- allocate space for local storage. 14092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1410864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateSUBSPImm (ARMEncoding encoding) 14114c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{ 14124c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0 14134c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen // ARM pseudo code... 14144c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (ConditionPassed()) 14154c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 14164c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen EncodingSpecificOperations(); 14174c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 14184c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if d == 15 then // Can only occur for ARM encoding 1419799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen ALUWritePC(result); // setflags is always FALSE here 14204c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen else 14214c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen R[d] = result; 14224c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if setflags then 14234c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.N = result<31>; 14244c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.Z = IsZeroBit(result); 14254c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.C = carry; 14264c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.V = overflow; 14274c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 14284c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif 14294c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 14304c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen bool success = false; 14312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 14324c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (!success) 14334c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 14344c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 14352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 14364c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 1437e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 14384c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (!success) 14394c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 14404c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen uint32_t imm32; 14414c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen switch (encoding) { 1442e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen case eEncodingT1: 1443e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 144460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT2: 144560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 144660c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 144760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT3: 144860c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 144960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 14504c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen case eEncodingA1: 145160c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 14524c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen break; 14534c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen default: 14544c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 14554c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 14564c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen addr_t sp_offset = imm32; 14574c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen addr_t addr = sp - sp_offset; // the adjusted stack pointer value 14584c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 14599bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 14609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 14619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 14624c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 14632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 14644c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 14654c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 14664c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return true; 14674c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen} 14684c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 146908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP. 14702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 14712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1472ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{ 1473ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0 1474ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen // ARM pseudo code... 1475ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (ConditionPassed()) 1476ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1477ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen EncodingSpecificOperations(); 1478ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1479ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen address = if index then offset_addr else R[n]; 1480ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1481ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if wback then R[n] = offset_addr; 1482ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1483ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif 1484ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 1485ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen bool success = false; 14862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 1487ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1488ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1489ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 14902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 1491ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 14922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1493e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1494ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1495ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 149691d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 1497ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen uint32_t imm12; 1498ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen switch (encoding) { 1499ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen case eEncodingA1: 1500108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 1501108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen imm12 = Bits32(opcode, 11, 0); 1502ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen break; 1503ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 1504ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1505ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1506ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen addr_t sp_offset = imm12; 1507ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen addr_t addr = sp - sp_offset; 1508ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 15099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 15109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 15119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 15129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 151391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt != 15) 1514ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 15159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_r0 + Rt; 15169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1517e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(Rt, &success); 1518ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1519ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1520cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1521ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1522ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1523ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen else 1524ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 15259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_pc; 15269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1527e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1528ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1529ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1530cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, addr, pc + 8, addr_byte_size)) 1531ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1532ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1533ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 1534ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 15359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 1536ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 15372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1538ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1539ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1540ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return true; 1541ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen} 1542ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 154308c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack. 154408c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data. 15452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 15462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1547799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{ 1548799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0 1549799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // ARM pseudo code... 1550799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (ConditionPassed()) 1551799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 1552799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1553799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = SP - imm32; 1554799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen SP = SP - imm32; 1555799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if single_regs then 1556799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1557799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = S[d+r]; address = address+4; 1558799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen else 1559799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1560799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // Store as two word-aligned words in the correct order for current endianness. 1561799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1562799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1563799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = address+8; 1564799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1565799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif 1566799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1567799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool success = false; 15682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t opcode = OpcodeAsUnsigned (&success); 1569799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1570799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1571799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 15722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (ConditionPassed()) 1573799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 15742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1575e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1576799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1577799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1578799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool single_regs; 1579587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1580799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t imm32; // stack offset 1581799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t regs; // number of registers 1582799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen switch (encoding) { 1583799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT1: 1584799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA1: 1585799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = false; 1586bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1587799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1588799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // If UInt(imm8) is odd, see "FSTMX". 1589799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 1590799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1591799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1592799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1593799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 1594799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT2: 1595799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA2: 1596799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = true; 1597bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1598799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1599799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0); 1600799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1601799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1602799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1603799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 1604799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen default: 1605799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1606799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1607799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1608799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1609799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t sp_offset = imm32; 1610799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t addr = sp - sp_offset; 1611799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t i; 1612799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 16139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 16149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 16159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 16169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1617799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for (i=d; i<regs; ++i) 1618799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 16199bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = start_reg + i; 16209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset ( dwarf_reg, addr - sp); 1621799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // uint64_t to accommodate 64-bit registers. 16229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1623799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1624799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1625cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 1626799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1627799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr += reg_byte_size; 1628799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1629799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1630799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 16319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 1632799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 16332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1634799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1635799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1636799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return true; 1637799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen} 1638799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1639587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack. 1640587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data. 1641587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool 1642587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny ChenEmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1643587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{ 1644587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0 1645587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // ARM pseudo code... 1646587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (ConditionPassed()) 1647587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1648587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1649587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen address = SP; 1650587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen SP = SP + imm32; 1651587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if single_regs then 1652587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 1653587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen S[d+r] = MemA[address,4]; address = address+4; 1654587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen else 1655587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 1656587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1657587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Combine the word-aligned words in the correct order for current endianness. 1658587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1659587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1660587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif 1661587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1662587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool success = false; 1663587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 1664587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1665587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1666587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1667587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (ConditionPassed()) 1668587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1669587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen const uint32_t addr_byte_size = GetAddressByteSize(); 1670e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1671587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1672587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1673587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool single_regs; 1674587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1675587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t imm32; // stack offset 1676587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t regs; // number of registers 1677587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen switch (encoding) { 1678587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT1: 1679587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA1: 1680587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = false; 1681bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1682587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1683587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // If UInt(imm8) is odd, see "FLDMX". 1684587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 1685587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1686587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1687587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1688587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 1689587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT2: 1690587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA2: 1691587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = true; 1692bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1693587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1694587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0); 1695587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1696587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1697587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1698587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 1699587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen default: 1700587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1701587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1702587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1703587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1704587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t sp_offset = imm32; 1705587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t addr = sp; 1706587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t i; 1707587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint64_t data; // uint64_t to accomodate 64-bit registers. 1708587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 17099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 17109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 17119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 17129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1713587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for (i=d; i<regs; ++i) 1714587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 17159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = start_reg + i; 17169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1717cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, reg_byte_size, 0, &success); 1718587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1719587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 17209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1721587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1722587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr += reg_byte_size; 1723587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1724587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1725587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 17269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 1727587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1728587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1729587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1730587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1731587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return true; 1732587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen} 1733587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1734b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI) 1735b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool 1736b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny ChenEmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1737b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{ 1738b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0 1739b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // ARM pseudo code... 1740b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (ConditionPassed()) 1741b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 1742b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen EncodingSpecificOperations(); 1743b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen CallSupervisor(); 1744b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 1745b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif 1746b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 1747b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen bool success = false; 1748b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 1749b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!success) 1750b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 1751b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 1752b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (ConditionPassed()) 1753b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 1754e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1755b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen addr_t lr; // next instruction address 1756b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!success) 1757b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 1758b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t imm32; // the immediate constant 1759b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t mode; // ARM or Thumb mode 1760b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen switch (encoding) { 1761b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingT1: 1762b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = (pc + 2) | 1u; // return address 1763b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 7, 0); 1764b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeThumb; 1765b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 1766b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingA1: 1767b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = pc + 4; // return address 1768b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 23, 0); 1769b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeARM; 1770b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 1771b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen default: 1772b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 1773b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 17749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 17759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 17769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextSupervisorCall; 17779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediate (mode, imm32); 1778b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1779b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 1780b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 1781b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return true; 1782b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen} 1783b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 1784c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional. 1785c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool 1786c315f860b343cf4a143f43c7d570d151989abb46Johnny ChenEmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1787c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{ 1788c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0 1789c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // ARM pseudo code... 1790c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen EncodingSpecificOperations(); 1791c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen ITSTATE.IT<7:0> = firstcond:mask; 1792c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif 1793c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 1794c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen bool success = false; 1795c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 1796c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen if (!success) 1797c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return false; 1798c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 1799c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.InitIT(Bits32(opcode, 7, 0)); 1800c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return true; 1801c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen} 1802c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 18033b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address. 18043b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool 18053b620b38cd170c20ea607585021ab2ab50286943Johnny ChenEmulateInstructionARM::EmulateB (ARMEncoding encoding) 18063b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{ 18073b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0 18083b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // ARM pseudo code... 18093b620b38cd170c20ea607585021ab2ab50286943Johnny Chen if (ConditionPassed()) 18103b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 18113b620b38cd170c20ea607585021ab2ab50286943Johnny Chen EncodingSpecificOperations(); 18123b620b38cd170c20ea607585021ab2ab50286943Johnny Chen BranchWritePC(PC + imm32); 18133b620b38cd170c20ea607585021ab2ab50286943Johnny Chen } 18143b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif 18153b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 18163b620b38cd170c20ea607585021ab2ab50286943Johnny Chen bool success = false; 18173b620b38cd170c20ea607585021ab2ab50286943Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 18183b620b38cd170c20ea607585021ab2ab50286943Johnny Chen if (!success) 18193b620b38cd170c20ea607585021ab2ab50286943Johnny Chen return false; 18203b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 18219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (ConditionPassed()) 18229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 18239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 18249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1825e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 18269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!success) 18279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 182853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 18299ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen int32_t imm32; // PC-relative offset 18309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen switch (encoding) { 18319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT1: 18329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 18339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1834e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 18359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 18369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 18379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT2: 18389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1839e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 18409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 18419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 18429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT3: 18439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 18449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 1845bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 18469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm6 = Bits32(opcode, 21, 16); 1847bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1848bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 18499ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 185053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 18519ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<21>(imm21); 1852e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 18539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 18549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 18559ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 18569ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT4: 18579ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 1858bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 18599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 1860bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1861bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 18629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 18639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I1 = !(J1 ^ S); 18649ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I2 = !(J2 ^ S); 186553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 18669ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1867e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 18689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 18699ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 18709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 18719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingA1: 18729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1873e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 18749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 18759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 18769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 18779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 18789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 18799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 18809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 18819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 18829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return true; 18833b620b38cd170c20ea607585021ab2ab50286943Johnny Chen} 18843b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 188553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 188653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value. They do not affect the condition flags. 188753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ 188853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool 188953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny ChenEmulateInstructionARM::EmulateCB (ARMEncoding encoding) 189053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{ 189153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0 189253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // ARM pseudo code... 189353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen EncodingSpecificOperations(); 189453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if nonzero ^ IsZero(R[n]) then 189553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen BranchWritePC(PC + imm32); 189653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif 189753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 189853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool success = false; 189953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 190053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 190153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 190253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 190353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // Read the register value from the operand register Rn. 1904e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 190553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 190653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 190753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 19089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 19099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1910e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 191153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 191253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 191353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 191453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 191553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm32; // PC-relative offset to branch forward 191653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool nonzero; 191753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen switch (encoding) { 191853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen case eEncodingT1: 1919bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 192053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen nonzero = BitIsSet(opcode, 11); 1921e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 19229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 192353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen break; 192453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen default: 192553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 192653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen } 192753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (nonzero ^ (reg_val == 0)) 192853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!BranchWritePC(context, target)) 192953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 193053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 193153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 193253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen} 193353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 193460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 193560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 193660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table. 193760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// 193860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 193960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 194060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table. 194160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH 194260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool 194360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny ChenEmulateInstructionARM::EmulateTB (ARMEncoding encoding) 194460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{ 194560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0 194660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // ARM pseudo code... 194760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(n); 194860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if is_tbh then 194960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 195060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen else 195160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+R[m], 1]); 195260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen BranchWritePC(PC + 2*halfwords); 195360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif 195460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 195560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool success = false; 195660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 195760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 195860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 195960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 196060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rn; // the base register which contains the address of the table of branch lengths 196160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 196260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool is_tbh; // true if table branch halfword 196360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen switch (encoding) { 196460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen case eEncodingT1: 196560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rn = Bits32(opcode, 19, 16); 196660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rm = Bits32(opcode, 3, 0); 196760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen is_tbh = BitIsSet(opcode, 4); 196860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (Rn == 13 || BadReg(Rm)) 196960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 197060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (InITBlock() && !LastInITBlock()) 197160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 197260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen break; 197360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen default: 197460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 197560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen } 197660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 197760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // Read the address of the table from the operand register Rn. 197860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // The PC can be used, in which case the table immediately follows this instruction. 1979e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t base = ReadCoreReg(Rm, &success); 198060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 198160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 198260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 198360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the table index 1984e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t index = ReadCoreReg(Rm, &success); 198560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 198660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 198760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 198860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the offsetted table address 198960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen addr_t addr = base + (is_tbh ? index*2 : index); 199060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 199160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // PC-relative offset to branch forward 199260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EmulateInstruction::Context context; 199360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextTableBranchReadMemory; 1994104c8b69863f229033d616245f56243ca51f1de9Johnny Chen uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 199560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 199660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 199760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 1998e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 199960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 200060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 200160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 200260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // target address 2003e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = pc + offset; 200460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextRelativeBranchImmediate; 200560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.SetModeAndImmediateSigned (eModeThumb, 4 + offset); 200660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 200760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!BranchWritePC(context, target)) 200860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 200960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 201060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return true; 201160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen} 201260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 20138fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// This instruction adds an immediate value to a register value, and writes the result to the destination 20148fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// register. It can optionally update the condition flags based on the result. 20158fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chenbool 20168fa2059234b17e9c377eea49b01f0ea084f66843Johnny ChenEmulateInstructionARM::EmulateADDImmARM (ARMEncoding encoding) 20178fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen{ 20188fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#if 0 20198fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // ARM pseudo code... 20208fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if ConditionPassed() then 20218fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EncodingSpecificOperations(); 20228fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 20238fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if d == 15 then 20248fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen ALUWritePC(result); // setflags is always FALSE here 20258fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen else 20268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen R[d] = result; 20278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if setflags then 20288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.N = result<31>; 20298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.Z = IsZeroBit(result); 20308fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.C = carry; 20318fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.V = overflow; 20328fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#endif 20338fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 20348fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool success = false; 20358fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 20368fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!success) 20378fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 20388fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 20398fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (ConditionPassed()) 20408fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 20418fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t Rd, Rn; 20428fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 20438fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool setflags; 20448fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen switch (encoding) 20458fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 20468fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 20478fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 20488fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 20498fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 20508fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 20518fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 20528fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen default: 20538fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 20548fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 20558fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 20568fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // Read the first operand. 2057157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 20588fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!success) 20598fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 20608fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 20618fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 20628fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 20638fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EmulateInstruction::Context context; 20648fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen context.type = EmulateInstruction::eContextImmediate; 20658fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen context.SetNoArgs (); 20668fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 20678fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 20688fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 20698fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 20708fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return true; 20718fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen} 20728fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 2073d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result 2074d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 207526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 20769f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateADDReg (ARMEncoding encoding) 207726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 207826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0 207926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // ARM pseudo code... 208026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if ConditionPassed() then 208126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen EncodingSpecificOperations(); 208226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 208326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 208426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if d == 15 then 208526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen ALUWritePC(result); // setflags is always FALSE here 208626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 208726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen R[d] = result; 208826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if setflags then 208926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.N = result<31>; 209026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.Z = IsZeroBit(result); 209126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.C = carry; 209226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.V = overflow; 209326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif 209426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 209526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen bool success = false; 209626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 209726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 209826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 209926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 210026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (ConditionPassed()) 210126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 210226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen uint32_t Rd, Rn, Rm; 2103d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen ARM_ShifterType shift_t; 2104d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2105ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen bool setflags; 210626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen switch (encoding) 210726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 2108d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen case eEncodingT1: 2109d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rd = Bits32(opcode, 2, 0); 2110d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rn = Bits32(opcode, 5, 3); 2111d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rm = Bits32(opcode, 8, 6); 2112d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen setflags = !InITBlock(); 2113d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2114d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 211526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen case eEncodingT2: 2116bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 211726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen Rm = Bits32(opcode, 6, 3); 2118ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen setflags = false; 2119d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2120d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 212126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (Rn == 15 && Rm == 15) 212226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 2123d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 2124d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen return false; 212526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen break; 21268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 21278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 21288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 21298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rm = Bits32(opcode, 3, 0); 21308fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 21318fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 21328fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 213326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen default: 213426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 213526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 213626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 213726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the first operand. 2138157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 213926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 214026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 214126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 214226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the second operand. 2143157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 214426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 214526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 214626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 2147e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 21488fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 21499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 21509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 21519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 21529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 2153ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 215410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2155ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 215626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 215726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return true; 215826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 215926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 216034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (immediate) adds a register value and an immediate value. 216134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 216234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 216334075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMNImm (ARMEncoding encoding) 216434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 216534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 216634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 216734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 216834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 216934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 217034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 217134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 217234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 217334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 217434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 217534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 217634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 217734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 217834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 217934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 218034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 218134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 218234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t imm32; // the immediate value to be compared with 218334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 218434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 218534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 10, 8); 218634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = Bits32(opcode, 7, 0); 218734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 218834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 218934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 219034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 219134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 219234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 219334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 219434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from the operand register Rn. 219534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 219634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 219734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 219834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 219934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 220034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 220134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 220234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 220334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs (); 220434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 220534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 220634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 220734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 220834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 220934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 221034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (register) adds a register value and an optionally-shifted register value. 221134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 221234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 221334075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMNReg (ARMEncoding encoding) 221434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 221534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 221634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 221734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 221834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 221934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 222034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 222134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 222234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 222334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 222434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 222534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 222634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 222734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 222834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 222934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 223034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 223134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 223234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 223334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rm; // the second operand 223434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 223534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 223634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 223734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 223834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 2, 0); 223934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 5, 3); 224034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 224134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 224234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 224334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT2: 224434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 224534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 6, 3); 224634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 224734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 224834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (Rn < 8 && Rm < 8) 224934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 225034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (Rn == 15 || Rm == 15) 225134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 225234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 225334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 225434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 225534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 225634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 225734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 225834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 225934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 226034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rn. 226134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 226234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 226334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 226434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 226534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rm. 226634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 226734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 226834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 226934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 227034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 227134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 227234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 227334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 227434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 227534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs(); 227634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 227734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 227834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 227934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 228034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 228134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 228234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (immediate) subtracts an immediate value from a register value. 228334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2284d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool 228534075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMPImm (ARMEncoding encoding) 2286d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{ 2287d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0 2288d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // ARM pseudo code... 2289d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if ConditionPassed() then 2290d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen EncodingSpecificOperations(); 2291d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2292d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.N = result<31>; 2293d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.Z = IsZeroBit(result); 2294d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.C = carry; 2295d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.V = overflow; 2296d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif 2297d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2298d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen bool success = false; 2299d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 2300d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if (!success) 2301d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2302d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2303d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t Rn; // the first operand 2304d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t imm32; // the immediate value to be compared with 2305d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen switch (encoding) { 2306d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen case eEncodingT1: 2307d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen Rn = Bits32(opcode, 10, 8); 2308d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen imm32 = Bits32(opcode, 7, 0); 230934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 231034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 231134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2312d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen break; 2313d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen default: 2314d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2315d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen } 2316d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // Read the register value from the operand register Rn. 2317e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 2318d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if (!success) 2319d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2320d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 232110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 232210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 23239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 23249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 23259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 232610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 232710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 232810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2329d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return true; 2330d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen} 2331d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 233234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (register) subtracts an optionally-shifted register value from a register value. 233334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2334e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool 233534075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMPReg (ARMEncoding encoding) 2336e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{ 2337e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0 2338e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // ARM pseudo code... 2339e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if ConditionPassed() then 2340e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen EncodingSpecificOperations(); 2341e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2342e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2343e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.N = result<31>; 2344e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.Z = IsZeroBit(result); 2345e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.C = carry; 2346e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.V = overflow; 2347e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif 2348e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2349e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen bool success = false; 2350e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 2351e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2352e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2353e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2354e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rn; // the first operand 2355e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rm; // the second operand 235634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 235734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2358e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen switch (encoding) { 2359e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT1: 2360e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bits32(opcode, 2, 0); 2361e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 5, 3); 236234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 236334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2364e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 2365e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT2: 2366e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2367e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 6, 3); 236834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 236934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2370e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn < 8 && Rm < 8) 2371e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2372e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn == 15 || Rm == 15) 2373e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2374e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 237534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 237634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 237734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 237834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 2379e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen default: 2380e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2381e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen } 2382e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rn. 238334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 2384e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2385e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 238634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2387e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rm. 238834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 2389e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2390e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2391e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 239234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 239334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 239410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 23959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 23969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 23979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs(); 239810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 239910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 240010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2401e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return true; 2402e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen} 2403e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 240482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 240582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. It can 240682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result. 240782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool 240882f16aa9f19678ffa20b92a8df926e933940d34dJohnny ChenEmulateInstructionARM::EmulateASRImm (ARMEncoding encoding) 240982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{ 241082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0 241182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // ARM pseudo code... 241282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if ConditionPassed() then 241382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EncodingSpecificOperations(); 241482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 241582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if d == 15 then // Can only occur for ARM encoding 241682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 241782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen else 241882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen R[d] = result; 241982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if setflags then 242082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.N = result<31>; 242182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.Z = IsZeroBit(result); 242282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.C = carry; 242382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // APSR.V unchanged 242482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif 242582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 242641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen return EmulateShiftImm(encoding, SRType_ASR); 242741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 242841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 242941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 243041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. 243141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update 243241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result. 243341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 243441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateASRReg (ARMEncoding encoding) 243541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 243641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 243741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 243841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 243941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 244041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 244141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 244241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 244341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 244441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 244541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 244641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 244741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 244841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 244941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 245041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen return EmulateShiftReg(encoding, SRType_ASR); 245141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 245241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 245341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 245441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 245541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 245641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 245741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding) 245841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 245941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 246041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 246141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 246241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 246341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 246441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 246541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 246641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 246741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 246841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 246941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 247041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 247141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 247241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 247341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 247441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 247541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen return EmulateShiftImm(encoding, SRType_LSL); 247641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 247741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 247841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits, 247941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 248041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 248141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 248241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 248341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding) 248441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 248541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 248641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 248741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 248841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 248941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 249041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 249141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 249241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 249341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 249441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 249541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 249641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 249741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 249841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 249941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen return EmulateShiftReg(encoding, SRType_LSL); 250041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 250141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 250241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 250341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 250441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 250541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 250641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding) 250741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 250841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 250941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 251041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 251141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 251241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 251341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 251441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 251541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 251641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 251741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 251841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 251941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 252041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 252141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 252241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 252341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 252441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen return EmulateShiftImm(encoding, SRType_LSR); 252541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 252641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 252741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits, 252841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 252941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 253041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 253141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 253241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding) 253341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 253441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 253541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 253641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 253741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 253841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 253941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 254041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 254141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 254241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 254341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 254441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 254541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 254641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 254741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 254841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen return EmulateShiftReg(encoding, SRType_LSR); 254941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 255041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 2551eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 2552eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2553eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result. 2554eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 2555eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRORImm (ARMEncoding encoding) 2556eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2557eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2558eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2559eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2560eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2561eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2562eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 2563eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 2564eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 2565eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2566eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2567eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2568eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2569eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2570eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2571eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2572eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2573eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen return EmulateShiftImm(encoding, SRType_ROR); 2574eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2575eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2576eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 2577eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2578eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 2579eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result. 2580eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 2581eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRORReg (ARMEncoding encoding) 2582eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2583eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2584eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2585eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2586eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2587eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_n = UInt(R[m]<7:0>); 2588eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2589eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2590eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2591eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2592eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2593eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2594eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2595eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2596eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2597eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen return EmulateShiftReg(encoding, SRType_ROR); 2598eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2599eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2600eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 2601eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31]. 2602eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// 2603eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result. 2604eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag. 2605eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 2606eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRRX (ARMEncoding encoding) 2607eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2608eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2609eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2610eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2611eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2612eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 2613eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 2614eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 2615eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 2616eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2617eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2618eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2619eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2620eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2621eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2622eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2623eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2624eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen return EmulateShiftImm(encoding, SRType_RRX); 2625eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2626eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 262741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 262841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type) 262941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 263041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 263141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 263282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool success = false; 263382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 263482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (!success) 263582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 263682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 263782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (ConditionPassed()) 263882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 2639e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 2640e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the first operand register 2641e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t imm5; // encoding for the shift amount 264282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen uint32_t carry; // the carry bit after the shift operation 264382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool setflags; 2644eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2645eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Special case handling! 2646eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) -- Encoding T1 2647eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if (shift_type == SRType_ROR && encoding == eEncodingT1) 2648eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 2649eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 2650eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // have the same decoding of bit fields as the other Thumb2 shift operations. 2651eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen encoding = eEncodingT2; 2652eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen } 2653eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 265482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen switch (encoding) { 265582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT1: 2656eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Due to the above special case handling! 2657eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen assert(shift_type != SRType_ROR); 2658eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 265982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 2, 0); 266082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 5, 3); 266182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = !InITBlock(); 266282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 10, 6); 266382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 266482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT2: 2665eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.141 RRX 2666eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen assert(shift_type != SRType_RRX); 2667eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 266882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 11, 8); 266982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 267082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 267182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 267282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (BadReg(Rd) || BadReg(Rm)) 267382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 267482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 267582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingA1: 267682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 15, 12); 267782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 267882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 267982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 11, 7); 268082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 268182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen default: 268282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 268382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 268482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 2685eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) 2686eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if (shift_type == SRType_ROR && imm5 == 0) 2687eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_type = SRType_RRX; 2688eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 268982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // Get the first operand. 2690e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rm, &success); 269182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (!success) 269282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 269382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 2694eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Decode the shift amount if not RRX. 2695eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 269682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 2697e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 269882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 269982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // The context specifies that an immediate is to be moved into Rd. 270082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EmulateInstruction::Context context; 270182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 270282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.SetNoArgs (); 270382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 270410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2705ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 270682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 270782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return true; 270882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen} 270982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 2710e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool 271141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type) 2712e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{ 271341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 2714e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2715e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool success = false; 2716e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 2717e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 2718e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2719e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2720e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (ConditionPassed()) 2721e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 2722e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 2723e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rn; // the first operand register 2724e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the register whose bottom byte contains the amount to shift by 2725e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t carry; // the carry bit after the shift operation 2726e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool setflags; 2727e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen switch (encoding) { 2728e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT1: 2729e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 2, 0); 2730e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Rd; 2731e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 5, 3); 2732e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = !InITBlock(); 2733e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 2734e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT2: 2735e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 11, 8); 2736e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 19, 16); 2737e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 3, 0); 2738e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 2739e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 2740e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2741e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 2742e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingA1: 2743e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 15, 12); 2744e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 3, 0); 2745e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 11, 8); 2746e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 2747e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (Rd == 15 || Rn == 15 || Rm == 15) 2748e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2749e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 2750e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen default: 2751e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2752e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 2753e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2754e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the first operand. 2755e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rn, &success); 2756e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 2757e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2758e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the Rm register content. 2759e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadCoreReg (Rm, &success); 2760e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 2761e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2762e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2763e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the shift amount. 2764e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t amt = Bits32(val, 7, 0); 2765e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2766e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 2767e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2768e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // The context specifies that an immediate is to be moved into Rd. 2769e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen EmulateInstruction::Context context; 2770e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.type = EmulateInstruction::eContextImmediate; 2771e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.SetNoArgs (); 2772e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 277310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2774e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 2775e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 2776e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return true; 2777e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen} 2778e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 2779b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an 2780713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register. Optionally the address just above the highest of those locations 2781b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register. 2782b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool 2783b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline TiceEmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 2784b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{ 2785b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0 2786b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // ARM pseudo code... 2787b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ConditionPassed() 2788b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE (n); 2789b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice address = R[n]; 2790b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2791b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for i = 0 to 14 2792b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<i> == '1' then 2793b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice R[i] = MemA[address, 4]; address = address + 4; 2794b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<15> == '1' then 2795b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice LoadWritePC (MemA[address, 4]); 2796b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2797b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 2798b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2799b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2800b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif 2801b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2802b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool success = false; 2803b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 2804b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 2805b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2806b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2807b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (ConditionPassed()) 2808b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 2809b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t n; 2810b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t registers = 0; 2811b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool wback; 2812b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 2813b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice switch (encoding) 2814b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 2815b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT1: 2816b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’); 2817b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 10, 8); 2818b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 7, 0); 2819b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2820b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsClear (registers, n); 2821b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 2822b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitCount(registers) < 1) 2823b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2824b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 2825b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT2: 2826b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if W == ’1’ && Rn == ’1101’ then SEE POP; 2827b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2828b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 2829b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 2830b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is zero. 2831b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 2832b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 2833b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2834b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 2835b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 2) 2836b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2837b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2838b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 2839b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2840098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2841b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2842b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 2843b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2844b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback 2845b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice && BitIsSet (registers, n)) 2846b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2847b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 2848b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 2849b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingA1: 2850b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 2851b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 2852b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 2853b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 2854b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 1)) 2855b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2856b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 2857b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice default: 2858b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2859b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 2860b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2861b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice int32_t offset = 0; 2862b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2863b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 2864b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 286585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 28669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 28679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 28689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 28699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 28709bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 2871b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2872b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for (int i = 0; i < 14; ++i) 2873b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 2874b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, i)) 2875b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 287685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 28779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 2878b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && (n == 13)) // Pop Instruction 2879b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 2880b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2881b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[i] = MemA [address, 4]; address = address + 4; 2882cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 2883b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 2884b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2885b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2886b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2887b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2888b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2889b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice offset += addr_byte_size; 2890b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 2891b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 2892b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2893b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, 15)) 2894b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 2895b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //LoadWritePC (MemA [address, 4]); 289685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 28979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 2898cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 2899b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 2900b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2901e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 2902668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 2903b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2904b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 2905b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2906b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsClear (registers, n)) 2907b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 2908fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // R[n] = R[n] + 4 * BitCount (registers) 2909fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = addr_byte_size * BitCount (registers); 2910fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 29119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 2912b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2913b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 2914b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 2915b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 2916b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsSet (registers, n)) 2917b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[n] bits(32) UNKNOWN; 2918713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 2919b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 2920b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return true; 2921b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice} 2922713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2923713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers. 2924713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// The consecutive memorty locations end at this address and the address just below the lowest of those locations 2925713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// can optionally be written back tot he base registers. 2926713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 2927713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding) 2928713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 2929713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0 2930713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // ARM pseudo code... 2931713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ConditionPassed() then 2932713c2665a27096b68f3f8956222375354f1292f8Caroline Tice EncodingSpecificOperations(); 2933713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 2934713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2935713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for i = 0 to 14 2936713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if registers<i> == ’1’ then 2937713c2665a27096b68f3f8956222375354f1292f8Caroline Tice R[i] = MemA[address,4]; address = address + 4; 2938713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2939713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if registers<15> == ’1’ then 2940713c2665a27096b68f3f8956222375354f1292f8Caroline Tice LoadWritePC(MemA[address,4]); 2941713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2942713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2943713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2944713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif 2945713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2946713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool success = false; 2947713c2665a27096b68f3f8956222375354f1292f8Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 2948713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 2949713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 2950713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2951713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (ConditionPassed()) 2952713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 2953713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t n; 2954713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t registers = 0; 2955713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool wback; 2956713c2665a27096b68f3f8956222375354f1292f8Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 2957713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2958713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // EncodingSpecificOperations(); 2959713c2665a27096b68f3f8956222375354f1292f8Caroline Tice switch (encoding) 2960713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 2961713c2665a27096b68f3f8956222375354f1292f8Caroline Tice case eEncodingA1: 2962713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2963713c2665a27096b68f3f8956222375354f1292f8Caroline Tice n = Bits32 (opcode, 19, 16); 2964713c2665a27096b68f3f8956222375354f1292f8Caroline Tice registers = Bits32 (opcode, 15, 0); 2965713c2665a27096b68f3f8956222375354f1292f8Caroline Tice wback = BitIsSet (opcode, 21); 2966b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 2967713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2968713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 2969713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 2970713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2971713c2665a27096b68f3f8956222375354f1292f8Caroline Tice break; 2972713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2973713c2665a27096b68f3f8956222375354f1292f8Caroline Tice default: 2974713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 2975713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 2976713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 2977713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2978713c2665a27096b68f3f8956222375354f1292f8Caroline Tice int32_t offset = 0; 2979713c2665a27096b68f3f8956222375354f1292f8Caroline Tice addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2980713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2981713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 2982713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 2983713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2984713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size; 2985713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 29869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 29879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 29889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 29899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 29909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 2991713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 2992713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // for i = 0 to 14 2993713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for (int i = 0; i < 14; ++i) 2994713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 2995713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if registers<i> == ’1’ then 2996713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, i)) 2997713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 2998713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // R[i] = MemA[address,4]; address = address + 4; 29999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3000cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3001713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3002713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3003713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3004713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3005713c2665a27096b68f3f8956222375354f1292f8Caroline Tice offset += addr_byte_size; 3006713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3007713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3008713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3009713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if registers<15> == ’1’ then 3010713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // LoadWritePC(MemA[address,4]); 3011713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, 15)) 3012713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 30139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3014cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3015713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3016713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 301744c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen // In ARMv5T and above, this is an interworking branch. 3018668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3019713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3020713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3021713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3022713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 3023713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsClear (registers, n)) 3024713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3025713c2665a27096b68f3f8956222375354f1292f8Caroline Tice addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3026713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3027713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3028fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3029fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3030fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 30319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3032fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr = addr + offset; 3033713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3034713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3035713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3036713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3037713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 3038713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsSet (registers, n)) 3039713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3040713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3041713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 3042713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 3043713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3044713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3045713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3046713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register. 30470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool 30480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline TiceEmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 30490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{ 30500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0 30510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // ARM pseudo code... 30520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ConditionPassed() then 30530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 30540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice address = R[n] - 4*BitCount(registers); 30550b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30560b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for i = 0 to 14 30570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if registers<i> == ’1’ then 30580b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice R[i] = MemA[address,4]; address = address + 4; 30590b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if registers<15> == ’1’ then 30600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice LoadWritePC(MemA[address,4]); 30610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 30630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 30640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif 30650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool success = false; 30670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 30680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 30690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 30700b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30710b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (ConditionPassed()) 30720b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 30730b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t n; 30740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t registers = 0; 30750b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool wback; 30760b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 30770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice switch (encoding) 30780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 30790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingT1: 30800b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 30810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 30820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 3083b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is a zero. 30840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 30850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30860b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 30870b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) 30880b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitCount (registers) < 2) 30890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 30900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 30910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3093098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 30940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 30950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 30960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if wback && registers<n> == ’1’ then UNPREDICTABLE; 30970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 30980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 30990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 31010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingA1: 31030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 31040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 31050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 31060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 31070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31080b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 31090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 31100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 31110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 31130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice default: 31150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 31160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 31170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3118713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers); 3119713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 31200b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice int32_t offset = 0; 3121713c2665a27096b68f3f8956222375354f1292f8Caroline Tice addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3122713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3123713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3124713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3125713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3126713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = address - (addr_byte_size * BitCount (registers)); 31279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 31289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 31299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 31309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 31319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 31320b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for (int i = 0; i < 14; ++i) 31340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 31350b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, i)) 31360b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 31370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 31389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3139cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 31400b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 31410b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 31420b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31430b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 31440b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 31450b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31460b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice offset += addr_byte_size; 31470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 31480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 31490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if registers<15> == ’1’ then 31510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // LoadWritePC(MemA[address,4]); 31520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, 15)) 31530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 31549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3155cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 31560b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 31570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3158e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3159668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 31600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 31610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 31620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 31640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsClear (registers, n)) 31650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 31660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 31670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 31680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3169fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3170fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3171fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 31729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3173fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr = addr + offset; 31740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 31750b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 31760b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 31770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 31780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 31790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 3180713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 31810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 31820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return true; 31830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice} 318485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3185713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3186713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3187713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register. 318885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool 318985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline TiceEmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 319085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{ 319185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0 319285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ConditionPassed() then 319385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice EncodingSpecificOperations(); 319485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice address = R[n] + 4; 319585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 319685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for i = 0 to 14 319785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if registers<i> == ’1’ then 319885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice R[i] = MemA[address,4]; address = address + 4; 319985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if registers<15> == ’1’ then 320085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice LoadWritePC(MemA[address,4]); 320185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 320285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 320385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 320485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif 320585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 320685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool success = false; 320785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 320885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 320985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 321085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 321185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (ConditionPassed()) 321285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 321385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t n; 321485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t registers = 0; 321585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool wback; 321685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 321785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice switch (encoding) 321885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 321985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice case eEncodingA1: 322085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 322185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice n = Bits32 (opcode, 19, 16); 322285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice registers = Bits32 (opcode, 15, 0); 322385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice wback = BitIsSet (opcode, 21); 322485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 322585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 322685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 322785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 322885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 322985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice break; 323085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice default: 323185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 323285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 323385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // address = R[n] + 4; 323485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 323585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice int32_t offset = 0; 3236713c2665a27096b68f3f8956222375354f1292f8Caroline Tice addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3237713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3238713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3239713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3240713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3241713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = address + addr_byte_size; 324285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 32439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 32449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 32469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 32479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 324885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 324985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for (int i = 0; i < 14; ++i) 325085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 325185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, i)) 325285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 325385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 325485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 32559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3256cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 325785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 325885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 325985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 326085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 326185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 326285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 326385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice offset += addr_byte_size; 326485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 326585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 326685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 326785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if registers<15> == ’1’ then 326885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // LoadWritePC(MemA[address,4]); 326985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, 15)) 327085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 32719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3272cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 327385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 327485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3275e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3276668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 327785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 327885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 327985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 328085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 328185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsClear (registers, n)) 328285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 328385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 328485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 328585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3286fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3287fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3288fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 32899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3290fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr = addr + offset; 329185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 329285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 329385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 329485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 329585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 329685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsSet (registers, n)) 3297713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 329885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 329985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return true; 330085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice} 33010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3302ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and 3303ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register. 3304ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb) 3305ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 3306ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 3307ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 3308ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0 3309ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // ARM pseudo code... 3310ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (ConditionPassed()) 3311ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3312ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3313ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3314ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = if index then offset_addr else R[n]; 3315ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen data = MemU[address,4]; 3316ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if wback then R[n] = offset_addr; 3317ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if t == 15 then 3318ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3319ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen elsif UnalignedSupport() || address<1:0> = '00' then 3320ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen R[t] = data; 3321ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3322ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3323ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif 3324ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3325ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool success = false; 3326ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 3327ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3328ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3329ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3330ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (ConditionPassed()) 3331ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3332ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rt; // the destination register 3333ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rn; // the base register 3334ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t imm32; // the immediate offset used to form the address 3335ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t offset_addr; // the offset address 3336ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t address; // the calculated address 3337ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t data; // the literal data value from memory load 3338ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool add, index, wback; 3339ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen switch (encoding) { 3340ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen case eEncodingT1: 3341ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen Rt = Bits32(opcode, 5, 3); 3342ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen Rn = Bits32(opcode, 2, 0); 3343ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3344ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // index = TRUE; add = TRUE; wback = FALSE 3345ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen add = true; 3346ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen index = true; 3347ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen wback = false; 3348ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen break; 3349ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen default: 3350ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3351ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3352ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 3353ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3354ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3355ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (add) 3356ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base + imm32; 3357ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3358ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base - imm32; 3359ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3360ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = (index ? offset_addr : base); 3361ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3362ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (wback) 3363ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 33649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context ctx; 33659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice ctx.type = EmulateInstruction::eContextRegisterPlusOffset; 33669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 33679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 33689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base)); 33699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 3370ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3371ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3372ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3373ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3374ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Prepare to write to the Rt register. 33759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 33769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 33779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 3378ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3379ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Read memory from the address. 3380cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 3381ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3382ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3383ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3384ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Rt == 15) 3385ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3386ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Bits32(address, 1, 0) == 0) 3387ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3388668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3389ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3390ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3391ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3392ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3393ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3394ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3395ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3396ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3397ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3398ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3399ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3400ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3401ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3402ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return true; 3403ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 3404ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3405af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3406af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start at this address, and teh address just above the last 3407af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 3408fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 3409fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::EmulateSTM (ARMEncoding encoding) 3410fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 3411fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0 3412fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ConditionPassed() then 3413fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3414fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = R[n]; 3415fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3416fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for i = 0 to 14 3417fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if registers<i> == ’1’ then 3418fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 3419fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3420fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 3421fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = R[i]; 3422fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = address + 4; 3423fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3424fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if registers<15> == ’1’ then // Only possible for encoding A1 3425fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = PCStoreValue(); 3426fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 3427fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif 3428fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3429fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool success = false; 3430fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 3431fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3432fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3433fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3434fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (ConditionPassed ()) 3435fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3436fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t n; 3437fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t registers = 0; 3438fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool wback; 3439fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3440fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3441fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3442fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice switch (encoding) 3443fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3444fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT1: 3445fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE; 3446fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 10, 8); 3447fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 7, 0); 3448b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3449fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = true; 3450fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3451fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 3452fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitCount (registers) < 1) 3453fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3454fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3455fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3456fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3457fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT2: 3458fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3459fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 3460fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 3461b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3462fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 3463fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3464fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3465fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 2)) 3466fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3467fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3468fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3469fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback && BitIsSet (registers, n)) 3470fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3471fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3472fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3473fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3474fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingA1: 3475fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3476fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 3477fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 3478fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 3479fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3480fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3481fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 3482fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3483fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3484fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3485fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3486fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice default: 3487fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3488fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3489fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3490fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = R[n]; 3491fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = 0; 3492fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3493fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3494fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3495fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 34969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 34979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 34989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register base_reg; 34999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3500fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3501fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // for i = 0 to 14 3502fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for (int i = 0; i < 14; ++i) 3503fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3504fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int lowest_set_bit = 14; 3505fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if registers<i> == ’1’ then 3506fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, i)) 3507fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3508fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (i < lowest_set_bit) 3509fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice lowest_set_bit = i; 3510fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 3511fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 3512fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3513fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice WriteBits32UnknownToMemory (address + offset); 3514fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 3515fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3516fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = R[i]; 3517fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3518fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3519fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3520fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 35219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register data_reg; 35229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 35239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3524cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3525fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3526fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3527fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3528fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = address + 4; 3529fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset += addr_byte_size; 3530fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3531fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3532fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3533fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if registers<15> == ’1’ then // Only possible for encoding A1 3534fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = PCStoreValue(); 3535fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, 15)) 3536fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 35379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register pc_reg; 35389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 35399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 3540fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3541fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3542fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3543fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3544cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3545fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3546fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3547fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3548fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 3549fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback) 3550fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3551fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3552fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 35539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3554fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr_t data = address + offset; 3555fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3556fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3557fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3558fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3559fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 3560fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 3561fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3562af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 3563af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3564af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 35651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool 35661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline TiceEmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding) 35671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{ 35681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0 35691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ConditionPassed() then 35701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EncodingSpecificOperations(); 35711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 35721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 35731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for i = 0 to 14 35741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if registers<i> == ’1’ then 35751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 35761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; 35771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 35781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = R[i]; 35791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = address + 4; 35801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 35811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if registers<15> == ’1’ then 35821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = PCStoreValue(); 35831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 35841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 35851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif 35861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 35871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool success = false; 35881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 35891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 35901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 35911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 35921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (ConditionPassed ()) 35931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 35941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t n; 35951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t registers = 0; 35961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool wback; 35971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 35981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 35991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // EncodingSpecificOperations(); 36001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice switch (encoding) 36011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 36021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice case eEncodingA1: 36031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 36041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice n = Bits32 (opcode, 19, 16); 36051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice registers = Bits32 (opcode, 15, 0); 36061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice wback = BitIsSet (opcode, 21); 36071511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 36091511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 36101511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice break; 36121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice default: 36131511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36141511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 36171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice int32_t offset = 0; 36181511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 36191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 36201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36211511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36221511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = address - (addr_byte_size * BitCount (registers)) + 4; 36231511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36241511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EmulateInstruction::Context context; 36251511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 36261511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register base_reg; 36271511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 36281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36291511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // for i = 0 to 14 36301511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for (int i = 0; i < 14; ++i) 36311511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 36321511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice int lowest_bit_set = 14; 36331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if registers<i> == ’1’ then 36341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, i)) 36351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 36361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (i < lowest_bit_set) 36371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice lowest_bit_set = i; 36381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice //if i == n && wback && i != LowestSetBit(registers) then 36391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((i == n) && wback && (i != lowest_bit_set)) 36401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; 36411511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice WriteBits32UnknownToMemory (address + offset); 36421511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 36431511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 36441511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = R[i]; 36451511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 36461511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 36471511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36481511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register data_reg; 36501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 36511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3652cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 36531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = address + 4; 36571511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice offset += addr_byte_size; 36581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if registers<15> == ’1’ then 36621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = PCStoreValue(); 36631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, 15)) 36641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 36651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register pc_reg; 36661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 36671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 36681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 36691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 36701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 3672cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 36731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 36761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 36771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (wback) 36781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 3679af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 36801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 36811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetImmediateSigned (offset); 36821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice addr_t data = address + offset; 36831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 36841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 36851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 36871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return true; 36881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice} 36891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 3690af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 3691af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end just below this address, and the address of the first of 3692af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register. 3693b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool 3694b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline TiceEmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding) 3695b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{ 3696b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0 3697b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ConditionPassed() then 3698b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3699b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = R[n] - 4*BitCount(registers); 3700b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3701b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for i = 0 to 14 3702b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if registers<i> == ’1’ then 3703b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 3704b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3705b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 3706b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = R[i]; 3707b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = address + 4; 3708b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3709b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if registers<15> == ’1’ then // Only possible for encoding A1 3710b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = PCStoreValue(); 3711b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3712b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 3713b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif 3714b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3715b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3716b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool success = false; 3717b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 3718b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 3719b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3720b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3721b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (ConditionPassed ()) 3722b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3723b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t n; 3724b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t registers = 0; 3725b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool wback; 3726b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3727b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3728b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3729b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice switch (encoding) 3730b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3731b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingT1: 3732b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if W == ’1’ && Rn == ’1101’ then SEE PUSH; 3733b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 3734b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3735b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See PUSH 3736b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3737b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3738b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 3739b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 3740b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3741b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 3742b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3743b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 2) 3744b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3745b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3746b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback && BitIsSet (registers, n)) 3747b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3748b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 3749b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3750b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingA1: 3751b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH; 3752b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 3753b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3754b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See Push 3755b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3756b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3757b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 3758b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 3759b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 3760b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3761b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 1) 3762b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3763b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 3764b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3765b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice default: 3766b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3767b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3768b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3769b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = R[n] - 4*BitCount(registers); 3770b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3771b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice int32_t offset = 0; 3772b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3773b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 3774b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3775b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3776b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = address - (addr_byte_size * BitCount (registers)); 3777b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3778b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EmulateInstruction::Context context; 3779b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 3780b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register base_reg; 3781b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3782b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3783b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // for i = 0 to 14 3784b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for (int i = 0; i < 14; ++i) 3785b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3786b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t lowest_set_bit = 14; 3787b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if registers<i> == ’1’ then 3788b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, i)) 3789b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3790b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (i < lowest_set_bit) 3791b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice lowest_set_bit = i; 3792b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 3793b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 3794b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3795b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice WriteBits32UnknownToMemory (address + offset); 3796b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 3797b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3798b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = R[i]; 3799b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3800b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 3801b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3802b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3803b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register data_reg; 3804b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3805b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3806cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3807b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3808b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3809b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3810b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = address + 4; 3811b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset += addr_byte_size; 3812b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3813b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3814b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3815b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if registers<15> == ’1’ then // Only possible for encoding A1 3816b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = PCStoreValue(); 3817b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, 15)) 3818b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3819b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register pc_reg; 3820b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3821b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 3822b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3823b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 3824b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3825b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3826cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3827b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3828b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3829b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3830b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 3831b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback) 3832b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 3833af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3834af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 3835af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetImmediateSigned (offset); 3836af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice addr_t data = address + offset; 3837af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3838af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3839af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3840af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3841af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return true; 3842af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice} 3843af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3844af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 3845af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start just above this address, and the address of the last 3846af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 3847af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool 3848af556564f80fd417a9158754f5e2ee692e183f6dCaroline TiceEmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding) 3849af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{ 3850af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0 3851af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ConditionPassed() then 3852af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EncodingSpecificOperations(); 3853af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = R[n] + 4; 3854af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3855af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for i = 0 to 14 3856af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if registers<i> == ’1’ then 3857af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if i == n && wback && i != LowestSetBit(registers) then 3858af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = bits(32) UNKNOWN; 3859af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 3860af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = R[i]; 3861af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = address + 4; 3862af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3863af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if registers<15> == ’1’ then 3864af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = PCStoreValue(); 3865af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3866af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 3867af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif 3868af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3869af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool success = false; 3870af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 3871af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 3872af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3873af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3874af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (ConditionPassed()) 3875af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3876af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t n; 3877af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t registers = 0; 3878af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool wback; 3879af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3880af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3881af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // EncodingSpecificOperations(); 3882af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice switch (encoding) 3883af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3884af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice case eEncodingA1: 3885af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3886af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice n = Bits32 (opcode, 19, 16); 3887af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice registers = Bits32 (opcode, 15, 0); 3888af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice wback = BitIsSet (opcode, 21); 3889af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3890af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3891af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((n == 15) && (BitCount (registers) < 1)) 3892af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3893af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice break; 3894af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice default: 3895af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3896af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3897af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = R[n] + 4; 3898af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3899af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice int32_t offset = 0; 3900af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3901af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 3902af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3903af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3904af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = address + addr_byte_size; 3905af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3906af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EmulateInstruction::Context context; 3907af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextRegisterStore; 3908af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register base_reg; 3909af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3910af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3911af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t lowest_set_bit = 14; 3912af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // for i = 0 to 14 3913af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for (int i = 0; i < 14; ++i) 3914af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3915af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if registers<i> == ’1’ then 3916af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, i)) 3917af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3918af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (i < lowest_set_bit) 3919af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice lowest_set_bit = i; 3920af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if i == n && wback && i != LowestSetBit(registers) then 3921af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 3922af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = bits(32) UNKNOWN; 3923af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice WriteBits32UnknownToMemory (address + offset); 3924af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // else 3925af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 3926af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3927af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = R[i]; 3928af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3929af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 3930af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3931af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3932af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register data_reg; 3933af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3934af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3935cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3936af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3937af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3938af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3939af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = address + 4; 3940af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset += addr_byte_size; 3941af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3942af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3943af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3944af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if registers<15> == ’1’ then 3945af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = PCStoreValue(); 3946af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, 15)) 3947af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3948af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register pc_reg; 3949af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3950af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 3951af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3952af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 3953af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3954af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3955cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3956af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 3957af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 3958af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 3959af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 3960af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (wback) 3961af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 3962b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset = addr_byte_size * BitCount (registers); 3963b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 3964b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetImmediateSigned (offset); 3965b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice addr_t data = address + offset; 3966b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3967b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 3968b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3969b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 3970b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return true; 3971b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice} 39727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 39737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 39747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 39757fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool 39767fac857ec72051dc0a91b027719c275ea672a470Caroline TiceEmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding) 39777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{ 39787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0 39797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ConditionPassed() then 39807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 39817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 39827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = if index then offset_addr else R[n]; 39837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if UnalignedSupport() || address<1:0> == ’00’ then 39847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = R[t]; 39857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else // Can only occur before ARMv7 39867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = bits(32) UNKNOWN; 39877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if wback then R[n] = offset_addr; 39887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif 39897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 39907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool success = false; 39917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 39927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 39937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 39947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 39957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (ConditionPassed()) 39967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 39977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 39987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 39997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t t; 40007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t n; 40017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t imm32; 40027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool index; 40037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool add; 40047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool wback; 40057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 40067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice switch (encoding) 40077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 40087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT1: 40097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32); 40107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 2, 0); 40117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 5, 3); 40127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 10, 6) << 2; 40137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 40157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 40167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = false; 40177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 40187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 40197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT2: 40217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32); 40227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 10, 8); 40237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = 13; 40247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 40257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 40277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 40287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 40297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 40307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 40317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT3: 40337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if Rn == ’1111’ then UNDEFINED; 40347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 40357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 40367fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40377fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 40387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 40397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 40407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 11, 0); 40417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 40437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 40447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 40457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 40467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 then UNPREDICTABLE; 40487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (t == 15) 40497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 40507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 40517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40527fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT4: 40537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT; 40547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH; 40557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 40567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((Bits32 (opcode, 19, 16) == 15) 40577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 40587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 40597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 40617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 40627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 40637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0); 40647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 40667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = BitIsSet (opcode, 10); 40677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = BitIsSet (opcode, 9); 40687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = BitIsSet (opcode, 8); 40697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 40717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((t == 15) || (wback && (n == t))) 40727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 40737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 40747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice default: 40767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 40777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 40787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t offset_addr; 40807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t address; 4081b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 40827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 40837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 40847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 40857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 40867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (add) 40887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address + imm32; 40897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 40907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address - imm32; 40917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // address = if index then offset_addr else R[n]; 40937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (index) 40947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = offset_addr; 40957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 40967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = base_address; 40977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 40987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EmulateInstruction::Context context; 40997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterStore; 41007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice Register base_reg; 41017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 41027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 41037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if UnalignedSupport() || address<1:0> == ’00’ then 41047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 41057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 41067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = R[t]; 41077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 41087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 41097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 41107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 41117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice Register data_reg; 41127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 41137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice int32_t offset = address - base_address; 41147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4115cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 41167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 41177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 41187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 41197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 41207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = bits(32) UNKNOWN; 41217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice WriteBits32UnknownToMemory (address); 41227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 41237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 41247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if wback then R[n] = offset_addr; 41257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (wback) 41267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 41277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterLoad; 41287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetAddress (offset_addr); 41297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 41307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 41317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 41327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 41337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return true; 41347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice} 4135af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 41363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 41373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory. The offset register value can optionally be shifted. 41383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool 41393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline TiceEmulateInstructionARM::EmulateSTRRegister (ARMEncoding encoding) 41403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{ 41413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0 41423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ConditionPassed() then 41433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 41443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 41453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 41463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = if index then offset_addr else R[n]; 41473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if t == 15 then // Only possible for encoding A1 41483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = PCStoreValue(); 41493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 41503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = R[t]; 41513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then 41523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = data; 41533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else // Can only occur before ARMv7 41543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = bits(32) UNKNOWN; 41553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if wback then R[n] = offset_addr; 41563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif 41573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool success = false; 41593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 41603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 41613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 41623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (ConditionPassed()) 41643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 41653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 41663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t t; 41683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t n; 41693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t m; 41703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice ARM_ShifterType shift_t; 41713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t shift_n; 41723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool index; 41733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool add; 41743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool wback; 41753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 41773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice switch (encoding) 41783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 41793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT1: 41803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 41813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 41823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 2, 0); 41833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 5, 3); 41843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 8, 6); 41853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 41873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 41883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 41893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 41903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 41923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 41933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = 0; 41943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 41953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 41963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT2: 41973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if Rn == ’1111’ then UNDEFINED; 41983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (Bits32 (opcode, 19, 16) == 15) 41993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 42023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 42033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 42043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 42053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 42073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 42083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 42093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 42103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 42123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 42133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = Bits32 (opcode, 5, 4); 42143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 || BadReg(m) then UNPREDICTABLE; 42163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ((t == 15) || (BadReg (m))) 42173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 42193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingA1: 42213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 42223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if P == ’0’ && W == ’1’ then SEE STRT; 42233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 42243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 42253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 42263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 42273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 42293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = BitIsSet (opcode, 24); 42303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = BitIsSet (opcode, 23); 42313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 42323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 42343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t typ = Bits32 (opcode, 6, 5); 42353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 42363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = DecodeImmShift(typ, imm5, shift_t); 42373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if m == 15 then UNPREDICTABLE; 42393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (m == 15) 42403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 42433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback && ((n == 15) || (n == t))) 42443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 42473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 42483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice default: 42493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 42513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t offset_addr; 42533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t address; 42543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice int32_t offset = 0; 42553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 42573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 42583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 42613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 42623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4265e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen offset = Shift (Rm_data, shift_t, shift_n, APSR_C); 42663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 42683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (add) 42693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address + offset; 42703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 42713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address - offset; 42723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // address = if index then offset_addr else R[n]; 42743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (index) 42753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = offset_addr; 42763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 42773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = base_address; 42783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t data; 42803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 then // Only possible for encoding A1 42813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (t == 15) 42823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = PCStoreValue(); 42833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 42843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 42853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = R[t]; 42863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 42873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 42893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 42903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EmulateInstruction::Context context; 42923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterStore; 42933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 42943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then 42953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (UnalignedSupport () 42963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || (BitIsClear (address, 1) && BitIsClear (address, 0)) 42973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || CurrentInstrSet() == eModeARM) 42983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 42993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = data; 43003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 43013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice Register base_reg; 43023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 43033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 43043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice Register data_reg; 43053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 43063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 43073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4308cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 43093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 43103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 43113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 43123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 43133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = bits(32) UNKNOWN; 43143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice WriteBits32UnknownToMemory (address); 43153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 43163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback then R[n] = offset_addr; 43173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback) 43183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 43193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterLoad; 43203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetAddress (offset_addr); 43213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 43223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 43233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 43243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 43253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 43263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return true; 43273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice} 432873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 432973a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool 433073a29de4b8f59594fd7a559c05fa795afe754551Caroline TiceEmulateInstructionARM::EmulateSTRBThumb (ARMEncoding encoding) 433173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{ 433273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0 433373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ConditionPassed() then 433473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 433573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 433673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = if index then offset_addr else R[n]; 433773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice MemU[address,1] = R[t]<7:0>; 433873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if wback then R[n] = offset_addr; 433973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif 434073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 434173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 434273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool success = false; 434373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 434473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 434573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 434673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 434773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (ConditionPassed ()) 434873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 434973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t t; 435073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t n; 435173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t imm32; 435273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool index; 435373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool add; 435473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool wback; 435573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 435673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice switch (encoding) 435773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 435873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT1: 435973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 436073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 2, 0); 436173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 5, 3); 436273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 10, 6); 436373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 436473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 436573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 436673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 436773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 436873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 436973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 437073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT2: 437173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if Rn == ’1111’ then UNDEFINED; 437273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 437373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 437473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 437573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 437673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 437773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 437873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 11, 0); 437973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 438073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 438173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 438273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 438373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 438473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 438573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) then UNPREDICTABLE; 438673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (BadReg (t)) 438773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 438873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 438973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 439073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT3: 439173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRBT; 439273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 439373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 439473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 439573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 439673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 439773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 439873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 439973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 7, 0); 440073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 440173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 440273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = BitIsSet (opcode, 10); 440373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = BitIsSet (opcode, 9); 440473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = BitIsSet (opcode, 8); 440573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 440673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 440773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ((BadReg (t)) || (wback && (n == t))) 440873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 440973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 441073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 441173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice default: 441273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 441373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 441473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 441573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t offset_addr; 441673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t address; 441773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 441873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 441973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 442073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 442173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 442273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (add) 442373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address + imm32; 442473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 442573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address - imm32; 442673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 442773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // address = if index then offset_addr else R[n]; 442873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (index) 442973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = offset_addr; 443073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 443173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = base_address; 443273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4433cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice // MemU[address,1] = R[t]<7:0> 443473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice Register base_reg; 443573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 443673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 443773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice Register data_reg; 443873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 443973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 444073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EmulateInstruction::Context context; 444173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterStore; 444273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 444373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 444473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 444573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 444673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 444773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 444873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data = Bits32 (data, 7, 0); 444973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4450cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, 1)) 445173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 445273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 445373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if wback then R[n] = offset_addr; 445473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (wback) 445573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 445673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterLoad; 445773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetAddress (offset_addr); 445873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 445973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 446073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 446173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 446273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 446373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 446473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return true; 446573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice} 44663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4467157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 4468157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// and writes the result to the destination register. It can optionally update the condition flags 4469157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// based on the result. 4470157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 4471157b959b101cbdddb81a690d00ff0697540d83e7Johnny ChenEmulateInstructionARM::EmulateADCImm (ARMEncoding encoding) 4472157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 4473157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 4474157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 4475157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 4476157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 4477157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 4478157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 4479157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 4480157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 4481157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 4482157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 4483157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 4484157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 4485157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 4486157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 4487157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 4488157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4489157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 4490157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 4491157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 4492157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4493157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4494157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (ConditionPassed()) 4495157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 4496157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn; 4497157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 4498157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 4499157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 4500157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 4501157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 4502157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 4503157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 4504157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 4505157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 4506157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 4507157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4508157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 4509157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 4510157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 4511157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 4512157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 4513157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 4514157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 4515157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 4516157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4517157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 4518157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 4519157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4520157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 4521157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4522157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 4523157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 4524157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 4525157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4526157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4527157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 4528157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4529157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 4530157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 4531157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 4532157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4533157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 4534157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4535157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 4536157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 4537157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 4538157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4539157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 4540157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// register value, and writes the result to the destination register. It can optionally update the 4541157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// condition flags based on the result. 4542157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 4543157b959b101cbdddb81a690d00ff0697540d83e7Johnny ChenEmulateInstructionARM::EmulateADCReg (ARMEncoding encoding) 4544157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 4545157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 4546157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 4547157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 4548157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 4549157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 4550157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 4551157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 4552157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 4553157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 4554157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 4555157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 4556157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 4557157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 4558157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 4559157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 4560157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 4561157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4562157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 4563157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 4564157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 4565157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4566157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4567157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (ConditionPassed()) 4568157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 4569157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn, Rm; 4570157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ARM_ShifterType shift_t; 4571157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 4572157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 4573157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 4574157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 4575157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 4576157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 4577157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 5, 3); 4578157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = !InITBlock(); 4579157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_t = SRType_LSL; 4580157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = 0; 4581157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT2: 4582157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 4583157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 4584157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 4585157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 4586157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 4587157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 4588157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4589157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 4590157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 4591157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 4592157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 4593157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 4594157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 4595157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 4596157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 4597157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 4598157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4599157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 4600157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 4601157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4602157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 4603157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4604157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 4605157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 4606157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 4607157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4608157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4609157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the second operand. 4610157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val2 = ReadCoreReg(Rm, &success); 4611157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 4612157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4613157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4614157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 4615157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 4616157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4617157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 4618157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 4619157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 4620157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4621157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 4622157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 4623157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 4624157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 4625157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 4626157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 4627e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 4628e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 4629e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 4630e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny ChenEmulateInstructionARM::EmulateANDImm (ARMEncoding encoding) 4631e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 4632e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 4633e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 4634e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 4635e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 4636e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND imm32; 4637e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 4638e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 4639e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 4640e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 4641e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 4642e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 4643e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 4644e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 4645e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 4646e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 4647e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4648e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 4649e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 4650e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 4651e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4652e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4653e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (ConditionPassed()) 4654e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 4655e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn; 4656e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 4657e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 4658e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 4659e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 4660e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 4661e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 4662e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 4663e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 4664e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 4665e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 4666de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (immediate); 4667e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 4668de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return EmulateTSTImm(eEncodingT1); 4669e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 4670e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4671e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 4672e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 4673e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 4674e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 4675e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 4676e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 4677e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 4678e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 4679e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4680e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 4681e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 4682e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4683e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 4684e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4685e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 4686157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 4687e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 4688e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4689e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4690e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & imm32; 4691e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4692e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 4693e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 4694e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 4695e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4696e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 4697e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4698e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 4699e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 4700e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 4701e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4702e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 4703e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags 4704e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// based on the result. 4705e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 4706e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny ChenEmulateInstructionARM::EmulateANDReg (ARMEncoding encoding) 4707e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 4708e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 4709e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 4710e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 4711e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 4712e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 4713e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND shifted; 4714e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 4715e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 4716e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 4717e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 4718e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 4719e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 4720e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 4721e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 4722e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 4723e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 4724e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4725e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 4726e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 4727e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 4728e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4729e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4730e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (ConditionPassed()) 4731e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 4732e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn, Rm; 4733e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ARM_ShifterType shift_t; 4734e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 4735e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 4736e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; 4737e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 4738e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 4739e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 4740e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 4741e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 5, 3); 4742e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = !InITBlock(); 4743e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_t = SRType_LSL; 4744e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_n = 0; 4745e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT2: 4746e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 4747e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 4748e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 4749e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 4750157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 4751de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (register); 4752e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 4753de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return EmulateTSTReg(eEncodingT2); 4754e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 4755e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4756e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 4757e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 4758e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 4759e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 4760e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 4761e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 4762e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 4763e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 4764e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 4765e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4766e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 4767e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 4768e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4769e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 4770e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4771e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 4772157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 4773e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 4774e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4775e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4776e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the second operand. 4777157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 4778e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 4779e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4780e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4781e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 4782e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & shifted; 4783e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4784e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 4785e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 4786e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 4787e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 4788e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 4789e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 4790e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 4791e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 4792e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 4793e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 47944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 4795e92b27c9262fd185359e6e2184b20d08953485f4Johnny Chen// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 47964d729c559d039181f250e0e3cd444fa73638f26fCaroline Ticebool 47974d729c559d039181f250e0e3cd444fa73638f26fCaroline TiceEmulateInstructionARM::EmulateLDRImmediateARM (ARMEncoding encoding) 47984d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice{ 47994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#if 0 48004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if ConditionPassed() then 48014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EncodingSpecificOperations(); 48024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 48034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = if index then offset_addr else R[n]; 48044d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = MemU[address,4]; 48054d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if wback then R[n] = offset_addr; 48064d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if t == 15 then 48074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 48084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice elsif UnalignedSupport() || address<1:0> = ’00’ then 48094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = data; 48104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else // Can only apply before ARMv7 48114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 48124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#endif 48134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool success = false; 48154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 48164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 48174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 48184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (ConditionPassed ()) 48204d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 48214d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 48224d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t t; 48244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t n; 48254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t imm32; 48264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool index; 48274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool add; 48284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool wback; 48294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice switch (encoding) 48314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 48324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice case eEncodingA1: 48334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if Rn == ’1111’ then SEE LDR (literal); 48344d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if P == ’0’ && W == ’1’ then SEE LDRT; 48354d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if Rn == ’1101’ && P == ’0’ && U == ’1’ && W == ’0’ && imm12 == ’000000000100’ then SEE POP; 48364d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 48374d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice t = Bits32 (opcode, 15, 12); 48384d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice n = Bits32 (opcode, 19, 16); 48394d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice imm32 = Bits32 (opcode, 11, 0); 48404d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48414d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 48424d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice index = BitIsSet (opcode, 24); 48434d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice add = BitIsSet (opcode, 23); 48444d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 48454d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48464d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback && n == t then UNPREDICTABLE; 48474d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback && (n == t)) 48484d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 48494d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48504d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice break; 48514d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48524d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice default: 48534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 48544d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 48554d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48564d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t address; 48574d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t offset_addr; 48584d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 48594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 48604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 48614d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48624d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 48634d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (add) 48644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = base_address + imm32; 48654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 48664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = base_address - imm32; 48674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // address = if index then offset_addr else R[n]; 48694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (index) 48704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = offset_addr; 48714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 48724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = base_address; 48734d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48744d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // data = MemU[address,4]; 48754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice Register base_reg; 48774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 48784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EmulateInstruction::Context context; 48804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 48814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 48824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 48844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 48854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 48864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback then R[n] = offset_addr; 48884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback) 48894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 48904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextAdjustBaseRegister; 48914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetAddress (offset_addr); 48924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 48934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 48944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 48954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 48964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if t == 15 then 48974d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (t == 15) 48984d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 48994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 49004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 49014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 49024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // LoadWritePC (data); 49034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 49044d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 49054d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice LoadWritePC (context, data); 49064d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 49074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 49084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 49094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 49104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // elsif UnalignedSupport() || address<1:0> = ’00’ then 49114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 49124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 49134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = data; 49144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 49154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 49164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 49174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 49184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 49194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // else // Can only apply before ARMv7 49204d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 49214d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 49224d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 49234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = ROR (data, Bits32 (address, 1, 0)); 49244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 49254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetImmediate (data); 49264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 49274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 49284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 49294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 49304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 49314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return true; 49324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice} 49334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 4934fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// LDR (register) calculates an address from a base register value and an offset register value, loads a word 4935fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 4936fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Ticebool 4937fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline TiceEmulateInstructionARM::EmulateLDRRegister (ARMEncoding encoding) 4938fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice{ 4939fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#if 0 4940fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ConditionPassed() then 4941fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4942fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 4943fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4944fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = if index then offset_addr else R[n]; 4945fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = MemU[address,4]; 4946fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if wback then R[n] = offset_addr; 4947fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if t == 15 then 4948fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 4949fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice elsif UnalignedSupport() || address<1:0> = ’00’ then 4950fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = data; 4951fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 4952fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if CurrentInstrSet() == InstrSet_ARM then 4953fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 4954fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 4955fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = bits(32) UNKNOWN; 4956fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#endif 4957fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4958fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool success = false; 4959fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 4960fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 4961fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 4962fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4963fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (ConditionPassed ()) 4964fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 4965fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4966fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4967fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t t; 4968fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t n; 4969fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t m; 4970fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool index; 4971fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool add; 4972fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool wback; 4973fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice ARM_ShifterType shift_t; 4974fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t shift_n; 4975fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4976fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice switch (encoding) 4977fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 4978fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT1: 4979fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4980fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4981fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 2, 0); 4982fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 5, 3); 4983fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 8, 6); 4984fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4985fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 4986fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 4987fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 4988fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 4989fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4990fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 4991fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 4992fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = 0; 4993fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4994fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 4995fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 4996fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT2: 4997fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if Rn == ’1111’ then SEE LDR (literal); 4998fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4999fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5000fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5001fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5002fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5003fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5004fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5005fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5006fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5007fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5008fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5009fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5010fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = Bits32 (opcode, 5, 4); 5011fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5012fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if BadReg(m) then UNPREDICTABLE; 5013fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BadReg (m)) 5014fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5015fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5016fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5017fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ((t == 15) && InITBlock() && !LastInITBlock()) 5018fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5019fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5020fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5021fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5022fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingA1: 5023fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5024fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if P == ’0’ && W == ’1’ then SEE LDRT; 5025fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5026fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5027fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5028fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5029fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5030fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 5031fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = BitIsSet (opcode, 24); 5032fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = BitIsSet (opcode, 23); 5033fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5034fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5035fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5036fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 5037fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 5038fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 5039fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5040fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if m == 15 then UNPREDICTABLE; 5041fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (m == 15) 5042fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5043fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5044fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5045fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback && ((n == 15) || (n == t))) 5046fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5047fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5048fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5049fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5050fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5051fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice default: 5052fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5053fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5054fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5055fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5056fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5057fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5058fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5059fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5060fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5061fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5062fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5063fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t offset_addr; 5064fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t address; 5065fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5066fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 5067fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_inst_cpsr, CPSR_C)); 5068fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5069fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5070fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (add) 5071fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn + offset; 5072fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5073fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn - offset; 5074fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5075fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // address = if index then offset_addr else R[n]; 5076fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (index) 5077fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = offset_addr; 5078fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5079fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = Rn; 5080fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5081fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // data = MemU[address,4]; 5082fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice Register base_reg; 5083fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5084fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5085fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EmulateInstruction::Context context; 5086fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5087fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5088fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5089fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5090fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5091fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5092fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5093fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback then R[n] = offset_addr; 5094fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback) 5095fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5096fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextAdjustBaseRegister; 5097fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetAddress (offset_addr); 5098fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5099fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5100fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5101fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5102fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 then 5103fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (t == 15) 5104fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5105fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 5106fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5107fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5108fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5109fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5110fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice LoadWritePC (context, data); 5111fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5112fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5113fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5114fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5115fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // elsif UnalignedSupport() || address<1:0> = ’00’ then 5116fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5117fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5118fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = data; 5119fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5120fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5121fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5122fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5123fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5124fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 5125fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5126fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ARM then 5127fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (CurrentInstrSet () == eModeARM) 5128fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5129fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 5130fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = ROR (data, Bits32 (address, 1, 0)); 5131fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5132fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetImmediate (data); 5133fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5134fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5135fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5136fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5137fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5138fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = bits(32) UNKNOWN; 5139fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice WriteBits32Unknown (t); 5140fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5141fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5142fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5143fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return true; 5144fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice} 514521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 514621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice// LDRB (immediate, Thumb) 514721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Ticebool 514821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline TiceEmulateInstructionARM::EmulateLDRBImmediate (ARMEncoding encoding) 514921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice{ 515021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#if 0 515121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if ConditionPassed() then 515221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 515321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 515421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = if index then offset_addr else R[n]; 515521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 515621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if wback then R[n] = offset_addr; 515721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#endif 515821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 515921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool success = false; 516021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 516121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 516221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 516321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 516421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (ConditionPassed ()) 516521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 516621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t t; 516721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t n; 516821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t imm32; 516921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool index; 517021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool add; 517121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool wback; 517221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 517321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 517421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice switch (encoding) 517521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 517621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT1: 517721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 517821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 2, 0); 517921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 5, 3); 518021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 10, 6); 518121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 518221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 518321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 518421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 518521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback= false; 518621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 518721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 518821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 518921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT2: 519021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if Rt == ’1111’ then SEE PLD; 519121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if Rn == ’1111’ then SEE LDRB (literal); 519221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 519321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 519421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 519521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 11, 0); 519621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 519721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 519821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 519921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 520021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = false; 520121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 520221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if t == 13 then UNPREDICTABLE; 520321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (t == 13) 520421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 520521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 520621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 520721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 520821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT3: 520921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if Rt == ’1111’ && P == ’1’ && U == ’0’ && W == ’0’ then SEE PLD; 521021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if Rn == ’1111’ then SEE LDRB (literal); 521121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if P == ’1’ && U == ’1’ && W == ’0’ then SEE LDRBT; 521221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if P == ’0’ && W == ’0’ then UNDEFINED; 521321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 521421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 521521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 521621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 521721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 521821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 521921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 7, 0); 522021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 522121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 522221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = BitIsSet (opcode, 10); 522321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = BitIsSet (opcode, 9); 522421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = BitIsSet (opcode, 8); 522521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 522621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 522721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BadReg (t) || (wback && (n == t))) 522821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 522921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 523021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 523121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 523221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice default: 523321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 523421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 523521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 523621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 523721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 523821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 523921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 524021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t address; 524121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t offset_addr; 524221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 524321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 524421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (add) 524521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn + imm32; 524621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 524721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn - imm32; 524821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 524921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // address = if index then offset_addr else R[n]; 525021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (index) 525121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = offset_addr; 525221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 525321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = Rn; 525421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 525521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 525621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice Register base_reg; 525721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice Register data_reg; 525821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 525921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 526021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 526121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EmulateInstruction::Context context; 526221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextRegisterLoad; 526321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 526421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 526521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 526621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 526721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 526821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 526921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 527021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 527121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 527221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if wback then R[n] = offset_addr; 527321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (wback) 527421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 527521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextAdjustBaseRegister; 527621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetAddress (offset_addr); 527721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 527821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 527921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 528021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 528121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return true; 528221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice} 5283f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5284f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 5285f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// zero-extends it to form a 32-bit word and writes it to a register. 5286f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Ticebool 5287f55261f53d56b4911c4c1ce419d893e5250d7150Caroline TiceEmulateInstructionARM::EmulateLDRBLiteral (ARMEncoding encoding) 5288f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice{ 5289f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#if 0 5290f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if ConditionPassed() then 5291f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 5292f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice base = Align(PC,4); 5293f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = if add then (base + imm32) else (base - imm32); 5294f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 5295f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#endif 5296f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5297f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool success = false; 5298f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 5299f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 5300f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5301f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5302f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (ConditionPassed ()) 5303f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 5304f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t t; 5305f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t imm32; 5306f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool add; 5307f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice switch (encoding) 5308f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 5309f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingT1: 5310f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if Rt == ’1111’ then SEE PLD; 5311f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’); 5312f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 5313f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 5314f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 5315f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5316f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 13 then UNPREDICTABLE; 5317f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 13) 5318f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5319f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5320f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 5321f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5322f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingA1: 5323f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’); 5324f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 5325f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 5326f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 5327f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5328f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 15 then UNPREDICTABLE; 5329f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 15) 5330f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5331f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 5332f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5333f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice default: 5334f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5335f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 5336f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5337f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // base = Align(PC,4); 5338f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t pc_val = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 5339f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 5340f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5341f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5342f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t base = AlignPC (pc_val); 5343f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5344f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice addr_t address; 5345f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // address = if add then (base + imm32) else (base - imm32); 5346f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (add) 5347f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base + imm32; 5348f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice else 5349f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base - imm32; 5350f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5351f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 5352f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EmulateInstruction::Context context; 5353f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.type = eContextRelativeBranchImmediate; 5354f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.SetImmediate (address - base); 5355f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5356f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 5357f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 5358f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5359f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 5360f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5361f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 5362f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 5363f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return true; 5364f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice} 536530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 536630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 536730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 536830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// optionally be shifted. 536930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Ticebool 537030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline TiceEmulateInstructionARM::EmulateLDRBRegister (ARMEncoding encoding) 537130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice{ 537230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#if 0 537330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ConditionPassed() then 537430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 537530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 537630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 537730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = if index then offset_addr else R[n]; 537830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice R[t] = ZeroExtend(MemU[address,1],32); 537930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if wback then R[n] = offset_addr; 538030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#endif 538130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 538230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool success = false; 538330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice const uint32_t opcode = OpcodeAsUnsigned (&success); 538430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 538530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 538630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 538730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (ConditionPassed ()) 538830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 538930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t t; 539030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t n; 539130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t m; 539230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool index; 539330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool add; 539430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool wback; 539530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice ARM_ShifterType shift_t; 539630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t shift_n; 539730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 539830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 539930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice switch (encoding) 540030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 540130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT1: 540230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 540330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 2, 0); 540430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 5, 3); 540530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 8, 6); 540630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 540730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 540830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 540930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 541030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 541130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 541230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 541330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 541430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = 0; 541530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 541630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 541730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT2: 541830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if Rt == ’1111’ then SEE PLD; 541930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if Rn == ’1111’ then SEE LDRB (literal); 542030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 542130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 542230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 542330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 542430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 542530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 542630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 542730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 542830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 542930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 543030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 543130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 543230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = Bits32 (opcode, 5, 4); 543330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 543430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 543530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 13) || BadReg (m)) 543630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 543730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 543830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 543930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingA1: 544030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 544130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if P == ’0’ && W == ’1’ then SEE LDRBT; 544230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 544330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 544430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 544530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 544630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 544730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 544830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = BitIsSet (opcode, 24); 544930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = BitIsSet (opcode, 23); 545030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 545130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 545230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 545330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 545430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 545530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 545630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 545730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 545830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 15) || (m == 15)) 545930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 546030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 546130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 546230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback && ((n == 15) || (n == t))) 546330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 546430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 546530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 546630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 546730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice default: 546830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 546930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 547030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 547130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset_addr; 547230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t address; 547330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 547430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 547530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 547630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 547730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 547830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 547930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 548030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 548130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 548230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 548330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 548430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 548530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 548630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (add) 548730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn + offset; 548830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 548930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn - offset; 549030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 549130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // address = if index then offset_addr else R[n]; 549230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (index) 549330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = offset_addr; 549430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 549530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = Rn; 549630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 549730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // R[t] = ZeroExtend(MemU[address,1],32); 549830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice Register base_reg; 549930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 550030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 550130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EmulateInstruction::Context context; 550230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextRegisterLoad; 550330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 550430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 550530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 550630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 550730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 550830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 550930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 551030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 551130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 551230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback then R[n] = offset_addr; 551330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback) 551430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 551530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextAdjustBaseRegister; 551630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetAddress (offset_addr); 551730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 551830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 551930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 552030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 552130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return true; 552230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice} 5523fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 55242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 55252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags based on 55262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 55272115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 55282115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateEORImm (ARMEncoding encoding) 55292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 55302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 55312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 55322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 55332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 55342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 55352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 55362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 55372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 55382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 55392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 55402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 55412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 55422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 55432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 55442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 55452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 55462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 55472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 55482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 55492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 55502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 55512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (ConditionPassed()) 55522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 55532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn; 55542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 55552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 55562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 55572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 55582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 55592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 55602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 55612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 55622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 55632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 55642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 55652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 55662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return EmulateTEQImm(eEncodingT1); 55672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 55682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 55692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 55702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 55712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 55722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 55732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 55742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 55752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 55762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 55772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 55782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 55792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 55802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 55812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 55822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 55832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 55842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 55852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 55862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 55872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 55882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 55892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 55902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 55912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 55922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 55932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 55942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 55952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 55962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 55972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 55982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 55992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 56002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 56022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value, and writes the result to the destination register. 56032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// It can optionally update the condition flags based on the result. 56042115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 56052115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateEORReg (ARMEncoding encoding) 56062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 56072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 56082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 56092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 56102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 56112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 56122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 56132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 56142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 56152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 56162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 56172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 56182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 56192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 56202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 56212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 56222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 56232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 56252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 56262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 56272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (ConditionPassed()) 56302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 56312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn, Rm; 56322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 56332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 56342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 56352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 56362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 56372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 56382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 56392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 56402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 5, 3); 56412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = !InITBlock(); 56422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_t = SRType_LSL; 56432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = 0; 56442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT2: 56452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 56462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 56472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 56482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 56492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 56502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == ‘1111’ && S == ‘1’ then SEE TEQ (register); 56512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 56522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return EmulateTEQReg(eEncodingT1); 56532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 56542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 56562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 56572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 56582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 56592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 56602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 56612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 56622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 56632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 56642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 56652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 56672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 56682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 56702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 56722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 56732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 56742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 56772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 56782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 56792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 56822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 56832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 56852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 56862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 56872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 56892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 56902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 56912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 56922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 56932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 56947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 56957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// writes the result to the destination register. It can optionally update the condition flags based 56967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 56977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 56987c5234db18ead0935e884429b3cace95b3a9dce4Johnny ChenEmulateInstructionARM::EmulateORRImm (ARMEncoding encoding) 56997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 57007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 57017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 57027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 57037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 57047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR imm32; 57057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 57067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 57077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 57087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 57097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 57107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 57117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 57127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 57137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 57147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 57157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 57177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 57187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 57197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (ConditionPassed()) 57227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 57237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn; 57247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 57257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 57267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 57277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 57287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 57297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 57307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 57317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 57327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 57337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 57347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if Rn == ‘1111’ then SEE MOV (immediate); 57357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 57367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return EmulateMOVRdImm(eEncodingT2); 57377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13) 57387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 57407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 57417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 57427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 57437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 57447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 57457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 57467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 57477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 57497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 57507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 57527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 57547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 57557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 57567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = val1 | imm32; 57597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 57617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 57627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 57637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 57657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57667c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 57677c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 57687c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 57697c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 57717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// value, and writes the result to the destination register. It can optionally update the condition flags based 57727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 57737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 57747c5234db18ead0935e884429b3cace95b3a9dce4Johnny ChenEmulateInstructionARM::EmulateORRReg (ARMEncoding encoding) 57757c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 57767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 57777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 57787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 57797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 57807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 57817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR shifted; 57827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 57837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 57847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 57857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 57867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 57877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 57887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 57897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 57907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 57917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 57927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 57947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 57957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 57967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 57977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 57987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (ConditionPassed()) 57997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 58007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn, Rm; 58017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ARM_ShifterType shift_t; 58027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 58037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 58047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; 58057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 58067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 58077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 58087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 58097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 5, 3); 58107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = !InITBlock(); 58117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_t = SRType_LSL; 58127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_n = 0; 58137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT2: 58147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 58157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 58167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 58177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 58187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 58197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if Rn == ‘1111’ then SEE MOV (register); 58207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 58217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return EmulateMOVRdRm(eEncodingT3); 58227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 58237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 58247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 58257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 58267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 58277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 58287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 58297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 58307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 58317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 58327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 58337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 58347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 58357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 58367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 58377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 58387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 58397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 58407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 58417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 58427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 58437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 58447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the second operand. 58457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 58467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 58477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 58487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 58497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 58502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 | shifted; 58517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 58527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 58537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 58547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 58557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 58567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 58577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 58587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 58597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 58607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 58617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 58622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 58632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// immediate value. It updates the condition flags based on the result, and discards the result. 58642115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 58652115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateTEQImm (ARMEncoding encoding) 58662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 58672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 58682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 58692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 58702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 58712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 58722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 58732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 58742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 58752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 58762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 58772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 58782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 58792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 58802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 58812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 58822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 58832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (ConditionPassed()) 58842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 58852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn; 58862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 58872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 58882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 58892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 58902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 58912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 58922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 58932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn)) 58942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 58952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 58962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 58972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 58982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 58992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 59002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 59012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 59032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 59052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 59062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 59072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 59102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 59122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 59132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 59142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 59162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 59182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 59192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 59202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 59222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value. It updates the condition flags based on the result, and discards 59232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 59242115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 59252115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateTEQReg (ARMEncoding encoding) 59262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 59272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 59282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 59292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 59302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 59312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 59322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 59332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 59342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 59352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 59362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 59372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 59382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 59402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 59412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 59422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (ConditionPassed()) 59452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 59462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn, Rm; 59472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 59482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 59492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 59502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 59512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 59522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 59532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 59542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 59552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 59562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn) || BadReg(Rm)) 59572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 59592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 59602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 59612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 59622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 59632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 59642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 59652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 59672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 59692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 59702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 59712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 59742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 59752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 59762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 59792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 59802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 59822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 59832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 59842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 59852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 59862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 59872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 59882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 59892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 59902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 5991de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 5992de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 5993de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 5994de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny ChenEmulateInstructionARM::EmulateTSTImm (ARMEncoding encoding) 5995de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 5996de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 5997de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 5998de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 5999de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 6000de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND imm32; 6001de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 6002de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 6003de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 6004de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 6005de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 6006de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6007de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 6008de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 6009de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 6010de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6011de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6012de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (ConditionPassed()) 6013de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 6014de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn; 6015de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 6016de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6017de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 6018de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 6019de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 6020de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 6021de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6022de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn)) 6023de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6024de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 6025de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 6026de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 6027de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6028de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 6029de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 6030de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6031de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 6032de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6033de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 6034de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 6035de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 6036de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6037de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6038de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & imm32; 6039de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6040de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 6041de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 6042de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 6043de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6044de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 6045de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6046de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 6047de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 6048de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 6049de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6050de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 6051de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 6052de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 6053de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny ChenEmulateInstructionARM::EmulateTSTReg (ARMEncoding encoding) 6054de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 6055de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 6056de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 6057de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 6058de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 6059de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6060de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND shifted; 6061de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 6062de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 6063de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 6064de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 6065de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 6066de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6067de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 6068de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen const uint32_t opcode = OpcodeAsUnsigned (&success); 6069de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 6070de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6071de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6072de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (ConditionPassed()) 6073de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 6074de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn, Rm; 6075de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen ARM_ShifterType shift_t; 6076de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 6077de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; 6078de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 6079de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 6080de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 6081de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 2, 0); 6082de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 5, 3); 6083de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_t = SRType_LSL; 6084de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_n = 0; 6085de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT2: 6086de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 6087de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 6088de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); 6089de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn) || BadReg(Rm)) 6090de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6091de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 6092de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 6093de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 6094de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 6095de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); 6096de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 6097de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 6098de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6099de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 6100de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6101de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 6102de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 6103de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 6104de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6105de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6106de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the second operand. 6107de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 6108de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 6109de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6110de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6111de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 6112de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & shifted; 6113de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6114de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 6115de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 6116de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 6117de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6118de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 6119de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 6120de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 6121de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 6122de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 6123de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 61242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 61252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 612664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 61272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 61282b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_arm_opcodes[] = 61292b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 61302b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 61312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 61322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 61332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 61359f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 61369f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 61372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 61399f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 6140864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 6141e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to ip 61429f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 61439f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 6144864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 61452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 6147864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 61482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push one register 61502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 6151c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 61522b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61532b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 61549b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 61559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 61562b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 6158587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Epilogue instructions 61592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 61602b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 61619f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 61629f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 61639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 6164b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 6165b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 6166b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 6167b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 6168b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 61693b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 61703b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 61713b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 61723b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 61733b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 6174b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 6175383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // To resolve ambiguity, "blx <label>" should come before "bl <label>". 6176383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 6177383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 6178383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 6179ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 6180ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 6181b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 6182b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 618328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // Data-processing instructions 618428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 6185157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 6186157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 6187157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 6188157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 61898fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (immediate) 6190157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 61918fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (register) 6192157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 6193e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 6194157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 6195e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 6196157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 61972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 61982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 61992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 62002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 62017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 62027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 62037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 62047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 62052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 62062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 62072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 62082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 6209de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 6210de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 6211de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 6212de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 6213de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6214de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 6215d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 6216d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 6217d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 6218d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 62193847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (immediate) 62203847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 62213847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (register) 62223847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 622334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 622434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 622534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) 622634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 622782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 622882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 62292ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // asr (register) 6230e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 62312ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 62322ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 62332ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 62342ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 62352ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 62362ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 62372ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 62382ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 6239eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 6240eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 6241eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 6242eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 6243eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 6244eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 624528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 624628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 6247b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 6248b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 62490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 6250713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 625185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 6252fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 62534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 6254fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 625530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 625630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 6257fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 6258fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 6259fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 6260fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 62611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 6262b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 6263af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 62643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 62653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" } 62661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 6267b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 62682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 62692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 62702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 62712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_arm_opcodes; ++i) 62722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 62732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 62742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_arm_opcodes[i]; 62752b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 62762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 62772b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 62782b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 62792b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 62802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 62812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 6282347320d16d98cffaadf3f888569100c43b241068Johnny Chen{ 62832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 62842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 62852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_thumb_opcodes[] = 62862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 62872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 62882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 62892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 62902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 62912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 62929f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 62939f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 62949f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 62952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 62962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 62979f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 6298e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to r7 62999f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 6300e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 63019f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 63022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 6303864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen // PC-relative load into register (see also EmulateADDSPRm) 6304c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 63052b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 63062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 6307864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 6308864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "add sp, sp, #imm"}, 6309864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 6310864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 63112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 63122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 6313d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 6314d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 63152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 63162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 63172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Epilogue instructions 63182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 63192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 6320864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 63219f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 63229f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 63239f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 6324d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 6325d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 6326b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 6327b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 6328b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 6329b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 6330c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 6331c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 6332c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 6333c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // If Then makes up to four following instructions conditional. 6334c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 63353b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 63363b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 63373b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 63383b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 63393b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 63403b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 63413b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 63423b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 63439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 6344b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 6345383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 6346383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 6347383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 6348383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 6349383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 6350ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 6351ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 635253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // compare and branch 635353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 635460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch byte 635560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 635660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch halfword 635760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 6358b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 6359b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 636026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Data-processing instructions 636126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 6362157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 6363157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 6364157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 6365157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 6366157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 6367157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // add (register) 63689f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 636926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 63709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 6371e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 6372157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 6373e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 6374e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 6375e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 63762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 63772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 63782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 63792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 63802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 63817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 63827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 63837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 63847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 63857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 63862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 63872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 63882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 63892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 6390de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 63912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 6392de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 6393de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 6394de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 6395de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 63967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 6397338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from high register to high register 63989f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 6399338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from low register to low register 64009f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 64017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // mov{s}<c>.w <Rd>, <Rm> 64027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 6403357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // move immediate 64049f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 64059f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 6406d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 6407d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 6408d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 6409d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 6410d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 641134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (immediate) 6412688926f8fb9a56964249ec970b4ae313a5b366d4Johnny Chen { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 641334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (register) 641434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 641534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xfff08f00, 0xeb100f00, ARMvAll, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 641634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 641734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 641834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm both from r0-r7) 641934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 642034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm not both from r0-r7) 642134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 642282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 642382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 64244d896db529a5fef200333ef673976528319279bdJohnny Chen { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 6425e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // asr (register) 6426e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 6427e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 64282ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 64292ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 64302ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 64312ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 64322ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 64332ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 64342ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 64352ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 64362ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 64372ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 6438eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 64392ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 6440eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 6441eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 6442eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 6443eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 6444eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 6445eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 6446eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 644726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 644826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 6449b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 6450b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 6451b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 64520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 6453ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 6454c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 6455c9de910d61f0471d18fced716fc10681ef432010Johnny Chen // Thumb2 PC-relative load into register 6456fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 6457fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 6458fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 645921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 646021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 646121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[>Rn>, #+/-<imm8>]{!}" }, 6462f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 646330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 646430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, eSize32,&EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 6465fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 6466fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 6467fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 6468fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 6469fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 6470b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 64717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 6472fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 6473fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 6474fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 6475fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 6476fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 6477fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 6478fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 6479fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 6480fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" } 64812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 64822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 64832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 64842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_thumb_opcodes; ++i) 64852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 64862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 64872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_thumb_opcodes[i]; 64882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 64892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 64902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 649164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 649231e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool 6493395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 649431e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{ 649531e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton m_arm_isa = 0; 6496395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton const char *arch_cstr = arch.AsCString (); 6497395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (arch_cstr) 6498395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton { 6499395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 6500395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 6501395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 6502395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 6503395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 6504395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 6505395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 6506395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 6507395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 6508395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 650931e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton } 651031e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton return m_arm_isa != 0; 651131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton} 651231e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 651331e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 651464c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 651564c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction () 651664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 651764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 651864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 651964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 652064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 652164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 652264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 652364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 65249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Context read_inst_context; 65259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.type = eContextReadOpcode; 65269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.SetNoArgs (); 65279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 652864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (m_inst_cpsr & MASK_CPSR_T) 652964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 653064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst_mode = eModeThumb; 6531cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 653264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 653364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 653464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 653564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 653664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 653764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst.opcode_type = eOpcode16; 653864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst.opcode.inst16 = thumb_opcode; 653964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 654064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 654164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 654264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst.opcode_type = eOpcode32; 6543cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice m_inst.opcode.inst32 = (thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success); 654464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 654564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 654664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 654764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 654864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 654964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst_mode = eModeARM; 655064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst.opcode_type = eOpcode32; 6551cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice m_inst.opcode.inst32 = MemARead(read_inst_context, pc, 4, 0, &success); 655264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 655364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 655464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 655564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 655664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 655764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst_mode = eModeInvalid; 655864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton m_inst_pc = LLDB_INVALID_ADDRESS; 655964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 656064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return success; 656164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 656264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 6563ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t 6564ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion () 6565ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 6566ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return m_arm_isa; 6567ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 6568ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 656964c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 657064c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ConditionPassed () 657164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 657264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (m_inst_cpsr == 0) 657364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 657464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 657564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton const uint32_t cond = CurrentCond (); 657664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 657764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond == UINT32_MAX) 657864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 657964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 658064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool result = false; 658164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton switch (UnsignedBits(cond, 3, 1)) 658264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 658364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 658464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 658564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 658664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 658764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 658864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 5: 658964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 659064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool n = (m_inst_cpsr & MASK_CPSR_N); 659164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool v = (m_inst_cpsr & MASK_CPSR_V); 659264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = n == v; 659364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 659464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 659564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 6: 659664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 659764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool n = (m_inst_cpsr & MASK_CPSR_N); 659864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool v = (m_inst_cpsr & MASK_CPSR_V); 659964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 660064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 660164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 660264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 7: 660364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = true; 660464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 660564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 660664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 660764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond & 1) 660864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = !result; 660964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return result; 661064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 661164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 66129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t 66139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::CurrentCond () 66149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 66159ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen switch (m_inst_mode) 66169ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 66179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 66189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeInvalid: 66199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 66209ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 66219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeARM: 66229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return UnsignedBits(m_inst.opcode.inst32, 31, 28); 66239ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 66249ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeThumb: 66259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 66269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // 'cond' field of the encoding. 66279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (m_inst.opcode_type == eOpcode16 && 66289ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 66299ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 66309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 66319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return Bits32(m_inst.opcode.inst16, 11, 7); 66329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 66339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else if (m_inst.opcode_type == eOpcode32 && 66349ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 66359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 66369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 66379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 66389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 66399ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return Bits32(m_inst.opcode.inst32, 25, 22); 66409ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 66419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 66429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return m_it_session.GetCond(); 66439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 66449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return UINT32_MAX; // Return invalid value 66459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 66469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 66479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 6648098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock() 6649098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 6650098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 6651098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 6652098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 6653098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 6654098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock() 6655098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 6656098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 6657098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 6658098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 6659098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 66609ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 66619ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 66629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 66639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 6664ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Check the current instruction set. 6665ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (CurrentInstrSet() == eModeARM) 66669ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 6667ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 66689ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 6669ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 66709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 667153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 667253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 667353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 66749ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 66759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 66769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 66779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 6678668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 66799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 66809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 66810f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 66820f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // we want to record it and issue a WriteRegister callback so the clients 66830f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // can track the mode changes accordingly. 66840f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen bool cpsr_changed = false; 66859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 66869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (BitIsSet(addr, 0)) 66879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 66880f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeThumb) 66890f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 66900f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeThumb); 66910f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 66920f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 66939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 6694668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetMode (eModeThumb); 66959ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 66969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else if (BitIsClear(addr, 1)) 66979ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 66980f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeARM) 66990f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 67000f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeARM); 67010f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 67020f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 67039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 6704668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetMode (eModeARM); 67059ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 67069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else 67079ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; // address<1:0> == '10' => UNPREDICTABLE 67089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 67090f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (cpsr_changed) 67100f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 6711558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 67120f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen return false; 67130f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 67149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 671553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 671653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 671753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 67189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 671964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 6720ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 6721ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 6722668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 6723ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 6724ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (ArchVersion() >= ARMv5T) 6725668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 6726ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 6727ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return BranchWritePC((const Context)context, addr); 6728ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 6729ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 673026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 673126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 6732668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 673326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 673426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 6735668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 673626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 673726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return BranchWritePC((const Context)context, addr); 673826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 673926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 6740ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode 6741ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet () 6742ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 6743ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return m_inst_mode; 6744ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 6745ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 6746ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 6747558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed. This function has a side effect of updating 6748558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary. 6749ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 6750ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 6751ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 6752558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr = m_inst_cpsr; 6753ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen switch (arm_or_thumb) 6754ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen { 6755ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen default: 6756ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return false; 6757ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen eModeARM: 6758ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Clear the T bit. 6759558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr &= ~MASK_CPSR_T; 6760ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 6761ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen eModeThumb: 6762ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Set the T bit. 6763558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr |= MASK_CPSR_T; 6764ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 6765ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen } 6766ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return true; 6767ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 6768ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 6769ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for 6770ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 6771ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 6772ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 6773ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport() 6774ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 6775ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return (ArchVersion() >= ARMv7); 6776ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 6777ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 6778bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information 6779bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions. This status 6780bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions. 6781bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult 6782bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 6783bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{ 6784bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint32_t result; 6785bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t carry_out; 6786bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t overflow; 6787bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 6788bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint64_t unsigned_sum = x + y + carry_in; 6789bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 6790bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 6791bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen result = UnsignedBits(unsigned_sum, 31, 0); 6792bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen carry_out = (result == unsigned_sum ? 0 : 1); 6793bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen overflow = ((int32_t)result == signed_sum ? 0 : 1); 6794bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 6795bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen AddWithCarryResult res = { result, carry_out, overflow }; 6796bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen return res; 6797bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen} 6798bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 6799157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenuint32_t 6800e39f22d1a369866808b8739c3cec15063d806833Johnny ChenEmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 6801157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 6802e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_kind, reg_num; 6803e39f22d1a369866808b8739c3cec15063d806833Johnny Chen switch (num) 6804157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 6805e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case SP_REG: 6806e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 6807e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 6808e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 6809e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case LR_REG: 6810e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 6811e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 6812e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 6813e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case PC_REG: 6814e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 6815e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_PC; 6816e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 6817e39f22d1a369866808b8739c3cec15063d806833Johnny Chen default: 6818e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (0 <= num && num < SP_REG) 6819e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 6820e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindDWARF; 6821e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = dwarf_r0 + num; 6822e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 6823157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 6824e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 6825e39f22d1a369866808b8739c3cec15063d806833Johnny Chen assert(0 && "Invalid register number"); 6826e39f22d1a369866808b8739c3cec15063d806833Johnny Chen *success = false; 6827e39f22d1a369866808b8739c3cec15063d806833Johnny Chen return ~0u; 6828e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 6829e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 6830e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 6831e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 6832e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // Read our register. 6833e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 6834e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 6835e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing an ARM instruction , PC reads as the address of the current 6836e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 8. 6837e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing a Thumb instruction , PC reads as the address of the current 6838e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 4. 6839e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (num == 15) 6840e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 6841e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (CurrentInstrSet() == eModeARM) 6842157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen val += 8; 6843e39f22d1a369866808b8739c3cec15063d806833Johnny Chen else 6844e39f22d1a369866808b8739c3cec15063d806833Johnny Chen val += 4; 6845157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 6846157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 6847157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return val; 6848157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 6849157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 6850ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the 6851ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result. 6852ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 6853ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 6854ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual: 6855ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 6856ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then // Can only occur for encoding A1 6857ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ALUWritePC(result); // setflags is always FALSE here 6858ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else 6859ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// R[d] = result; 6860ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if setflags then 6861ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.N = result<31>; 6862ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.Z = IsZeroBit(result); 6863ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.C = carry; 6864ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// // APSR.V unchanged 6865ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 6866ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which 6867ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u. 6868ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool 686910530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 687010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 687110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t Rd, 687210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen bool setflags, 687310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 687410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 6875ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{ 6876ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (Rd == 15) 6877ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 6878ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (!ALUWritePC (context, result)) 6879ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 6880ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 6881ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen else 6882ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 6883ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 6884ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 6885ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (setflags) 688610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return WriteFlags (context, result, carry, overflow); 688710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen } 688810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return true; 688910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen} 689010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 689110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 689210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual: 689310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 689410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>; 689510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result); 689610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry; 689710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow 689810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 689910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means 690010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags. 690110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool 690210530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context, 690310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 690410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 690510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 690610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{ 690710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen m_new_inst_cpsr = m_inst_cpsr; 690810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 690910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 691010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (carry != ~0u) 691110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen SetBit32(m_new_inst_cpsr, CPSR_C, carry); 691210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (overflow != ~0u) 691310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen SetBit32(m_new_inst_cpsr, CPSR_V, overflow); 691410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (m_new_inst_cpsr != m_inst_cpsr) 691510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen { 691610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 691710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 6918ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 6919ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return true; 6920ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen} 6921ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 692264c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 692364c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::EvaluateInstruction () 692464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 6925c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // Advance the ITSTATE bits to their values for the next instruction. 6926c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 6927c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.ITAdvance(); 6928c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 692964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 693064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 6931