EmulateInstructionARM.cpp revision 24bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7
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. 27b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 28b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 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) 1321697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 13359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 1346bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 1359b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 1362b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 1370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1380e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1390e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation 1400e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1410e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1420e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen 1432b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize () 1457dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{ 1462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1477dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen 1482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate () 15064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 1512b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1522b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 153fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 154fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 155fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 156fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 1579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 1599bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 160fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 161fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t random_data = rand (); 162fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 163fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 164cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address, random_data, addr_byte_size)) 165fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 166fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 167fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 168fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 169fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 170713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 171713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 172713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n) 173713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 1749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 1769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 177713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 17862ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen bool success; 179713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 180713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 181713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 182713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 183713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 184713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 185713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 186713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 187713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 188713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 189713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 19008c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to 19108c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates 19208c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data. 1932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1947bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 19564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 19664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0 19764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton // ARM pseudo code... 19864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (ConditionPassed()) 19964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 20064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton EncodingSpecificOperations(); 20164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton NullCheckIfThumbEE(13); 20264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = SP - 4*BitCount(registers); 20364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 20464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i = 0 to 14) 20564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 206bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (registers<i> == '1') 20764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 20864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 20964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = bits(32) UNKNOWN; 21064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 21164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = R[i]; 21264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = address + 4; 21364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 216bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (registers<15> == '1') // Only possible for encoding A1 or A2 21764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = PCStoreValue(); 21864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 21964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton SP = SP - 4*BitCount(registers); 22064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 22164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif 22264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 22364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 2247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 22564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2262b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 227e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 22864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 22964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 2303c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen uint32_t registers = 0; 23191d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 2323c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen switch (encoding) { 233aedde1c6a33b123031499800f56954adc86058f5Johnny Chen case eEncodingT1: 234108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 7, 0); 235aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // The M bit represents LR. 236bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 237ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 14); 238aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 239aedde1c6a33b123031499800f56954adc86058f5Johnny Chen if (BitCount(registers) < 1) 240aedde1c6a33b123031499800f56954adc86058f5Johnny Chen return false; 241aedde1c6a33b123031499800f56954adc86058f5Johnny Chen break; 2427dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT2: 2437dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // Ignore bits 15 & 13. 244108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0) & ~0xa000; 2457dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BitCount(registers) < 2 then UNPREDICTABLE; 2467dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen if (BitCount(registers) < 2) 2477dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 2487dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 2497dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT3: 250108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 2517dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BadReg(t) then UNPREDICTABLE; 25291d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (BadReg(Rt)) 2537dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 25491d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 2557dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 2563c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA1: 257108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0); 258a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // Instead of return false, let's handle the following case as well, 259a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // which amounts to pushing one reg onto the full descending stacks. 260a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 2613c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 2623c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA2: 263108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 2647dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if t == 13 then UNPREDICTABLE; 26591d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt == dwarf_sp) 2663c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen return false; 26791d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 2683c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 269ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 270ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 2713c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen } 272ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 27364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t addr = sp - sp_offset; 27464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton uint32_t i; 27564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 2789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 2799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 2802b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice Register sp_reg; 2812b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 28264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i=0; i<15; ++i) 28364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2847c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 28564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_r0 + i; 2872b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetRegisterToRegisterPlusOffset (dwarf_reg, sp_reg, addr - sp); 288e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(i, &success); 28964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 29064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 291cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 29264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 29364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr += addr_byte_size; 29464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 29564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 29664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2977c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 29864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_pc; 3009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 301e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 30264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 30364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 304e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (!MemAWrite (context, addr, pc, addr_byte_size)) 30564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 30664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 30764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 30864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton context.type = EmulateInstruction::eContextAdjustStackPointer; 3099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 31064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 3112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 31264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 31364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 31464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return true; 31564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 31664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 317ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from 318ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates 319ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data. 3202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 3217bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 322ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{ 323ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0 324ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // ARM pseudo code... 325ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (ConditionPassed()) 326ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 327ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(13); 328ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen address = SP; 329ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for i = 0 to 14 330bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 331ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 332bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 333ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if UnalignedAllowed then 334ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemU[address,4]); 335ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen else 336ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemA[address,4]); 337bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<13> == '0' then SP = SP + 4*BitCount(registers); 338bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<13> == '1' then SP = bits(32) UNKNOWN; 339ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 340ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif 341ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 342ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen bool success = false; 343ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 3447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 345ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 3462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 347e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 348ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 349ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 350ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t registers = 0; 351ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t Rt; // the destination register 352ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen switch (encoding) { 353ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT1: 354ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 7, 0); 355ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // The P bit represents PC. 356bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 357ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 15); 358ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 359ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (BitCount(registers) < 1) 360ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 361ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 362ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT2: 363ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Ignore bit 13. 364ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0) & ~0x2000; 365ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 366bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 367ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 368098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 369098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 370098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 371ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 372ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT3: 373ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 374ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 375098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 13) 376098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 377098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 378ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 379ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 380ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 381ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA1: 382ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0); 383ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Instead of return false, let's handle the following case as well, 384ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // which amounts to popping one reg from the full descending stacks. 385ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 386ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 387bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 388098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 389ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 390ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 391ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA2: 392ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 393ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 then UNPREDICTABLE; 394ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (Rt == dwarf_sp) 395ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 396ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 397ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 398ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen default: 399ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 400ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 401ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 402ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t addr = sp; 403ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t i, data; 404ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 4069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 4079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 4089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 4098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register sp_reg; 4108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 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; 4168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterPlusOffset (sp_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; 4298ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterPlusOffset (sp_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 4517bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 452bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{ 453bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0 454bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen // ARM pseudo code... 455bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (ConditionPassed()) 456bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 457bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen EncodingSpecificOperations(); 458bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (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; 472bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 4737bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 474bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 475e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 476bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (!success) 477bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 478bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t Rd; // the destination register 479bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t imm32; 480bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen switch (encoding) { 481bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingT1: 482bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = 7; 483bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 484bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 485bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingA1: 486bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = Bits32(opcode, 15, 12); 487bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 488bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 489bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen default: 490bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 491bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 492bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t sp_offset = imm32; 493bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t addr = sp + sp_offset; // a pointer to the stack area 494bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 4959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 4969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 4979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register sp_reg; 4989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 4999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, sp_offset); 500bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 5012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 502bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 503bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 504bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return true; 505bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen} 506bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 5072ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer. 5082ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register) 5092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 5112ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{ 5122ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0 5132ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // ARM pseudo code... 5142ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (ConditionPassed()) 5152ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 5162ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen EncodingSpecificOperations(); 5172ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen result = R[m]; 5182ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if d == 15 then 5192ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5202ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen else 5212ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen R[d] = result; 5222ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if setflags then 5232ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.N = result<31>; 5242ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.Z = IsZeroBit(result); 5252ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.C unchanged 5262ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.V unchanged 5272ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5282ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif 5292ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5302ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen bool success = false; 5312ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5332ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 534e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 5352ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (!success) 5362ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5372ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen uint32_t Rd; // the destination register 5382ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen switch (encoding) { 5392ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingT1: 5402ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 7; 5412ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 5422ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingA1: 5432ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 12; 5442ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 5452ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen default: 5462ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5472ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 5499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 5509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 5519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register sp_reg; 5529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 5539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, 0); 5542ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5552b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 5562ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5572ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5582ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return true; 5592ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen} 5602ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5611c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7). 5621c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register) 5632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5647bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 5651c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{ 5667bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdRm (opcode, encoding); 567338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen} 568338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen 569338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register. 570338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register) 571338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool 5727bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 573338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{ 5741c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0 5751c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // ARM pseudo code... 5761c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (ConditionPassed()) 5771c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 5781c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen EncodingSpecificOperations(); 5791c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen result = R[m]; 5801c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if d == 15 then 5811c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5821c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen else 5831c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen R[d] = result; 5841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if setflags then 5851c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.N = result<31>; 5861c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.Z = IsZeroBit(result); 5871c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.C unchanged 5881c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.V unchanged 5891c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 5901c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif 5911c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 5921c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen bool success = false; 5931c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 5947bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5951c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 5961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rm; // the source register 5971c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rd; // the destination register 598338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen bool setflags; 5991c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen switch (encoding) { 6001c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen case eEncodingT1: 6017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 6021c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen Rm = Bits32(opcode, 6, 3); 603338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = false; 6047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 6057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 606338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen break; 607338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen case eEncodingT2: 6087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 2, 0); 609338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen Rm = Bits32(opcode, 5, 3); 610338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = true; 6117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (InITBlock()) 6127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6131c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen break; 6147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT3: 6157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 6167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 6177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 6187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 6197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (setflags && (BadReg(Rd) || BadReg(Rm))) 6207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 6227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 6237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 624ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 62501d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen case eEncodingA1: 62601d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen Rd = Bits32(opcode, 15, 12); 62701d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen Rm = Bits32(opcode, 3, 0); 62801d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen setflags = BitIsSet(opcode, 20); 62901d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 63001d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 63101d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen if (Rd == 15 && setflags) 63201d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen return false; 63301d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen break; 6341c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen default: 6351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6361c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 6377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = ReadCoreReg(Rm, &success); 6381c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (!success) 6391c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6401c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 6411c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // The context specifies that Rm is to be moved into Rd. 6429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 6432b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.type = EmulateInstruction::eContextRegisterLoad; 6449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 6459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 6462b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetRegister (dwarf_reg); 647ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 64810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 649ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 6501c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 6511c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return true; 6521c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen} 6531c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 654357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register. It 655357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value. 656357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate) 657357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool 6587bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 659357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{ 660357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0 661357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // ARM pseudo code... 662357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if (ConditionPassed()) 663357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 664357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen EncodingSpecificOperations(); 665357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen result = imm32; 666357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if d == 15 then // Can only occur for ARM encoding 667357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen ALUWritePC(result); // setflags is always FALSE here 668357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen else 669357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen R[d] = result; 670357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if setflags then 671357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.N = result<31>; 672357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.Z = IsZeroBit(result); 673357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.C = carry; 674357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // APSR.V unchanged 675357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 676357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif 677357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 6787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 679357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 680357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t Rd; // the destination register 681357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the immediate value to be written to Rd 682357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 683357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen bool setflags; 684357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen switch (encoding) { 68589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT1: 68689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32(opcode, 10, 8); 68789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = !InITBlock(); 68889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 68989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice carry = APSR_C; 69089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 69189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 69289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 69389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT2: 69489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32(opcode, 11, 8); 69589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = BitIsSet(opcode, 20); 69689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 69789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (BadReg(Rd)) 69889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 69989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 70089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 70189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 70289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT3: 70389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 70489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 70589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 11, 8); 70689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = false; 70789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm4 = Bits32 (opcode, 19, 16); 70889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm3 = Bits32 (opcode, 14, 12); 70989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t i = Bit32 (opcode, 26); 71089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm8 = Bits32 (opcode, 7, 0); 71189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 71289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 71389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if BadReg(d) then UNPREDICTABLE; 71489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (BadReg (Rd)) 71589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 71689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice } 71789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 71889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 71989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingA1: 72089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 72189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 72289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 15, 12); 72389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = BitIsSet (opcode, 20); 72489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 72589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 72689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 72789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 72889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingA2: 72989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 73089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 73189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 15, 12); 73289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = false; 73389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm4 = Bits32 (opcode, 19, 16); 73489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm12 = Bits32 (opcode, 11, 0); 73589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = (imm4 << 12) | imm12; 73689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 73789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if d == 15 then UNPREDICTABLE; 73889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (Rd == 15) 73989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 74089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice } 74189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 74289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 74389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice default: 7449798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen return false; 745357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 746357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t result = imm32; 747357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 748357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // The context specifies that an immediate is to be moved into Rd. 7499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 7509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 7519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 752ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 75310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 754ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 755357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 756357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen return true; 757357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen} 758357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 7595c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 7605c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// register. These 32 bits do not depend on whether the source register values are considered to be signed values or 7615c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// unsigned values. 7625c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// 7635c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 7645c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// limited to only a few forms of the instruction. 7655c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Ticebool 7667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 7675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice{ 7685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#if 0 7695c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ConditionPassed() then 7705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice EncodingSpecificOperations(); 7715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 7725c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 7735c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice result = operand1 * operand2; 7745c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice R[d] = result<31:0>; 7755c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if setflags then 7765c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.N = result<31>; 7775c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.Z = IsZeroBit(result); 7785c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ArchVersion() == 4 then 7795c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.C = bit UNKNOWN; 7805c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // else APSR.C unchanged 7815c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.V always unchanged 7825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#endif 7835c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 7847bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7855c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 7865c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t d; 7875c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t n; 7885c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t m; 7895c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice bool setflags; 7905c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 7915c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // EncodingSpecificOperations(); 7925c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice switch (encoding) 7935c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 7945c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingT1: 7955c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 7965c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 2, 0); 7975c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 5, 3); 7985c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 2, 0); 7995c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = !InITBlock(); 8005c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8015c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 8025c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((ArchVersion() < ARMv6) && (d == n)) 8035c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8045c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8055c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 8065c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8075c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingT2: 8085c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 8095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 11, 8); 8105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 19, 16); 8115c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 3, 0); 8125c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = false; 8135c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8145c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 8155c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (BadReg (d) || BadReg (n) || BadReg (m)) 8165c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8175c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8185c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 8195c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8205c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingA1: 821bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 8225c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 19, 16); 8235c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 3, 0); 8245c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 11, 8); 8255c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = BitIsSet (opcode, 20); 8265c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8275c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 8285c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((d == 15) || (n == 15) || (m == 15)) 8295c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8305c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8315c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 8325c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((ArchVersion() < ARMv6) && (d == n)) 8335c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8345c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8355c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 8365c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8375c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice default: 8385c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8395c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8407bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 8417bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 8427bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 8435c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 8445c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8455c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!success) 8465c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8475c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8485c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 8495c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8505c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!success) 8515c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8525c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8535c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // result = operand1 * operand2; 8545c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t result = operand1 * operand2; 8555c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8565c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // R[d] = result<31:0>; 8575c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice Register op1_reg; 8585c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice Register op2_reg; 8595c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 8605c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 8615c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8625c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice EmulateInstruction::Context context; 8635c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice context.type = eContextMultiplication; 8645c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice context.SetRegisterRegisterOperands (op1_reg, op2_reg); 8655c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8665c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 8675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8695c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if setflags then 8705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (setflags) 8715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 8725c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.N = result<31>; 8735c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.Z = IsZeroBit(result); 874b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 8755c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 8765c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 877b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_new_inst_cpsr != m_opcode_cpsr) 8785c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 8795c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 8805c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8815c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8835c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() == 4 then 8845c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.C = bit UNKNOWN; 8855c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8865c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8875c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return true; 8885c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice} 8895c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 890d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 891d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the value. 89228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool 8937bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 89428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{ 89528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0 89628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // ARM pseudo code... 89728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if (ConditionPassed()) 89828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen { 89928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen EncodingSpecificOperations(); 90028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen result = NOT(imm32); 90128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if d == 15 then // Can only occur for ARM encoding 90228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 90328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen else 90428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen R[d] = result; 90528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if setflags then 90628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.N = result<31>; 90728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.Z = IsZeroBit(result); 90828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.C = carry; 90928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // APSR.V unchanged 91028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen } 91128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif 91233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 9137bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 91433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen { 91533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t Rd; // the destination register 916357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 917357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 91833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen bool setflags; 91933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen switch (encoding) { 92033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingT1: 92133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 11, 8); 92233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 923d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 92433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 92533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingA1: 92633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 15, 12); 92733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 928d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 929d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 930d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 931d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (Rd == 15 && setflags) 932d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 93333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 93433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen default: 93533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return false; 93633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 93733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t result = ~imm32; 93833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 93933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen // The context specifies that an immediate is to be moved into Rd. 9409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 9419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 9429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 943ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 94410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 945ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 94633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 94733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return true; 94828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen} 94928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 950d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 951d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the result. 952d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chenbool 9537bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 954d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen{ 955d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#if 0 956d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // ARM pseudo code... 957d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (ConditionPassed()) 958d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 959d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EncodingSpecificOperations(); 960d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 961d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen result = NOT(shifted); 962d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if d == 15 then // Can only occur for ARM encoding 963d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ALUWritePC(result); // setflags is always FALSE here 964d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen else 965d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen R[d] = result; 966d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if setflags then 967d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.N = result<31>; 968d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.Z = IsZeroBit(result); 969d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.C = carry; 970d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // APSR.V unchanged 971d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 972d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#endif 973d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 9747bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 975d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 976d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rm; // the source register 977d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rd; // the destination register 978d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ARM_ShifterType shift_t; 979d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 980d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen bool setflags; 981d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t carry; // the carry bit after the shift operation 982d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen switch (encoding) { 983d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT1: 984d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 2, 0); 985d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 5, 3); 986d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = !InITBlock(); 987d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_t = SRType_LSL; 988d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_n = 0; 989d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (InITBlock()) 990d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 991d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 992d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT2: 993d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 11, 8); 994d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 995d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 9963dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 997d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 998ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rm)) 999d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1000ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 1001d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingA1: 1002d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 15, 12); 1003d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 1004d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 10053dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 1006d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 1007d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen default: 1008d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1009d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 10107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1011d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t value = ReadCoreReg(Rm, &success); 1012d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!success) 1013d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1014d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1015d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry); 1016d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t result = ~shifted; 1017d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1018d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // The context specifies that an immediate is to be moved into Rd. 1019d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EmulateInstruction::Context context; 1020d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.type = EmulateInstruction::eContextImmediate; 1021d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.SetNoArgs (); 1022d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1023d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1024d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1025d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 1026d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return true; 1027d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen} 1028d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1029788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register). 1030788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal) 10312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 10327bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1033788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{ 1034788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0 1035788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen // ARM pseudo code... 1036788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (ConditionPassed()) 1037788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 1038788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1039788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen base = Align(PC,4); 1040788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen address = if add then (base + imm32) else (base - imm32); 1041788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen data = MemU[address,4]; 1042788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if t == 15 then 1043bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1044bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 1045788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = data; 1046788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else // Can only apply before ARMv7 1047788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 1048788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = ROR(data, 8*UInt(address<1:0>)); 1049788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else 1050788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = bits(32) UNKNOWN; 1051788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1052788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif 1053788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 10547bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1055788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 10567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1057e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1058788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 1059788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 1060809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen 1061809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen // PC relative immediate load context 10629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 10639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 10649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register pc_reg; 10659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 10669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 0); 10679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 1068c9de910d61f0471d18fced716fc10681ef432010Johnny Chen uint32_t Rt; // the destination register 1069788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t imm32; // immediate offset from the PC 1070c9de910d61f0471d18fced716fc10681ef432010Johnny Chen bool add; // +imm32 or -imm32? 1071c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t base; // the base address 1072c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t address; // the PC relative address 1073788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t data; // the literal data value from the PC relative load 1074788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen switch (encoding) { 1075788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen case eEncodingT1: 1076c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 10, 8); 1077788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1078c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = true; 1079c9de910d61f0471d18fced716fc10681ef432010Johnny Chen break; 1080c9de910d61f0471d18fced716fc10681ef432010Johnny Chen case eEncodingT2: 1081c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 15, 12); 1082c9de910d61f0471d18fced716fc10681ef432010Johnny Chen imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1083c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = BitIsSet(opcode, 23); 1084098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 1085c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1086788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen break; 1087788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen default: 1088788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 1089788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1090c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1091e39f22d1a369866808b8739c3cec15063d806833Johnny Chen base = Align(pc, 4); 1092c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (add) 1093c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base + imm32; 1094c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 1095c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base - imm32; 1096e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 1097e39f22d1a369866808b8739c3cec15063d806833Johnny Chen context.SetRegisterPlusOffset(pc_reg, address - base); 1098cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 1099788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 1100809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen return false; 1101c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1102c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Rt == 15) 1103c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1104c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Bits32(address, 1, 0) == 0) 1105c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1106c9de910d61f0471d18fced716fc10681ef432010Johnny Chen // In ARMv5T and above, this is an interworking branch. 1107668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 1108c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1109c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1110c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 1111c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1112c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1113c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1114c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1115c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1116c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1117c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1118c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else // We don't handle ARM for now. 1119c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1120c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1121788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1122788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return true; 1123788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen} 1124788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 11255b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP. 1126fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate) 11272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 11287bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1129fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{ 1130fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0 1131fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen // ARM pseudo code... 1132fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (ConditionPassed()) 1133fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 1134fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen EncodingSpecificOperations(); 1135bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1136fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if d == 15 then // Can only occur for ARM encoding 1137fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 1138fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen else 1139fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen R[d] = result; 1140fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if setflags then 1141fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.N = result<31>; 1142fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.Z = IsZeroBit(result); 1143fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.C = carry; 1144fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.V = overflow; 1145fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1146fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif 1147fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1148fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen bool success = false; 1149fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 11507bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1151fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 1152e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1153fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (!success) 1154fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 1155fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen uint32_t imm32; // the immediate operand 1156e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice uint32_t d; 1157e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice bool setflags; 1158e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice switch (encoding) 1159e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1160e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice case eEncodingT1: 1161bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1162e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice d = Bits32 (opcode, 10, 8); 1163e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice setflags = false; 1164e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice imm32 = (Bits32 (opcode, 7, 0) << 2); 1165e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1166e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice break; 1167e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1168e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice case eEncodingT2: 1169bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1170e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice d = 13; 1171e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice setflags = false; 1172e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1173e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1174e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice break; 1175e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1176e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice default: 1177e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1178fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1179fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t sp_offset = imm32; 1180fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1181fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 11829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 11839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 11849bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 1185fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1186e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (d == 15) 1187e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1188e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (!ALUWritePC (context, addr)) 1189e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1190e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice } 1191e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice else 1192e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1193e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1194e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1195e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice } 1196fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1197fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return true; 1198fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen} 1199fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1200fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP. 12015b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register) 12022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 12037bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 12045b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{ 12055b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0 12065b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen // ARM pseudo code... 12075b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (ConditionPassed()) 12085b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 12095b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen EncodingSpecificOperations(); 12105b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1211bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 12125b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if d == 15 then 12135b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen ALUWritePC(result); // setflags is always FALSE here 12145b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen else 12155b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen R[d] = result; 12165b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if setflags then 12175b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.N = result<31>; 12185b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.Z = IsZeroBit(result); 12195b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.C = carry; 12205b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.V = overflow; 12215b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 12225b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif 12235b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12245b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen bool success = false; 12255b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12267bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 12275b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 1228e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 12295b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 12305b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12315b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen uint32_t Rm; // the second operand 12325b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen switch (encoding) { 12335b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen case eEncodingT2: 12345b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen Rm = Bits32(opcode, 6, 3); 12355b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen break; 12365b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen default: 12375b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12385b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 1239e39f22d1a369866808b8739c3cec15063d806833Johnny Chen int32_t reg_value = ReadCoreReg(Rm, &success); 12405b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 12415b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12425b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12435b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 12445b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 12479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (reg_value); 12485b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 12505b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12515b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 12525b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return true; 12535b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen} 12545b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 12569b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or 12579b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM. 12589b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate) 12599b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 12607bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 12619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 12629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 12639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 12649b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 12659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 12669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 12679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 12689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC - 4; 12699b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 12709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC<31:1> : '1'; 12719b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if targetInstrSet == InstrSet_ARM then 12729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = Align(PC,4) + imm32; 12739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 12749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = PC + imm32; 12759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen SelectInstrSet(targetInstrSet); 12769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BranchWritePC(targetAddress); 12779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 12789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 12799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 12807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = true; 12819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 12827bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 12839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 12849bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1286e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 12879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 12889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 128953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t lr; // next instruction address 129053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 12919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen int32_t imm32; // PC-relative offset 12929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 1293d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen case eEncodingT1: 1294d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 1295e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1296bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 1297d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 1298bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1299bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 1300d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 1301d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I1 = !(J1 ^ S); 1302d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I2 = !(J2 ^ S); 130353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1304d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1305e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 13069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1307098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1308ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1309d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen break; 1310d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen } 13119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT2: 13129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 1313e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1314bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 13159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10H = Bits32(opcode, 25, 16); 1316bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1317bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 13189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10L = Bits32(opcode, 10, 1); 13199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I1 = !(J1 ^ S); 13209b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I2 = !(J2 ^ S); 132153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 13229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1323e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 13249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1325098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1326ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 13279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 13289b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1329c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen case eEncodingA1: 13302b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice lr = pc - 4; // return address 1331c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1332e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 13339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1334c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen break; 13359b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA2: 13362b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice lr = pc - 4; // return address 13379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1338e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 13399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 13409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 13419b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 13429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 13449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 13459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 13479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13489b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 13499b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 13509b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 13519b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 13529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and 13539b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register. 13549b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register) 13559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 13567bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 13579b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 13589b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 13599b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 13609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 13619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 13629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 13639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen target = R[m]; 13649b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 13659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 4; 13669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = next_instr_addr; 13679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 13689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 2; 1369bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice LR = next_instr_addr<31:1> : '1'; 13709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BXWritePC(target); 13719b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 13729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 13739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 13749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen bool success = false; 13759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 13767bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 13779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 13789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 13799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1380e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 13819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen addr_t lr; // next instruction address 13829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 13839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t Rm; // the register with the target address 13859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 13869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT1: 1387e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = (pc - 2) | 1u; // return address 13889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 6, 3); 13899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 13909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 13919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1392098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1393ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 13949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 13959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA1: 1396e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc - 4; // return address 13979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 3, 0); 13989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 13999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 14009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1401b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 14029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 14039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1405e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1406ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1407ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 14089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 14099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 14109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegister (dwarf_reg); 14119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 14129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1413668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 14149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 14169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 14179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 14189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 1419ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1420ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool 14217bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1422ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{ 1423ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0 1424ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // ARM pseudo code... 1425ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (ConditionPassed()) 1426ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 1427ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen EncodingSpecificOperations(); 1428ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen BXWritePC(R[m]); 1429ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1430ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif 1431ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 14327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1433ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 14349bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 14359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1436ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen uint32_t Rm; // the register with the target address 1437ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen switch (encoding) { 1438ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingT1: 1439ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 6, 3); 1440098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1441ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1442ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1443ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingA1: 1444ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 3, 0); 1445ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1446ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen default: 1447ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1448ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 14497bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1450e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1451ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1452ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 14539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 14549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 14559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1456668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetRegister (dwarf_reg); 1457668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 1458ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1459ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1460ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return true; 1461ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen} 1462ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 146359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 146459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// address and instruction set specified by a register as though it were a BX instruction. 146559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// 146659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// TODO: Emulate Jazelle architecture? 146759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 146859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chenbool 14697bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 147059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen{ 147159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#if 0 147259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // ARM pseudo code... 147359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (ConditionPassed()) 147459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 147559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen EncodingSpecificOperations(); 1476bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 147759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen BXWritePC(R[m]); 147859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen else 147959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if JazelleAcceptsExecution() then 148059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen SwitchToJazelleExecution(); 148159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen else 148259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen SUBARCHITECTURE_DEFINED handler call; 148359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 148459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#endif 148559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 14867bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 148759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 148859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen EmulateInstruction::Context context; 148959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 149059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen uint32_t Rm; // the register with the target address 149159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen switch (encoding) { 149259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen case eEncodingT1: 149359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Rm = Bits32(opcode, 19, 16); 149459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (BadReg(Rm)) 149559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 149659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (InITBlock() && !LastInITBlock()) 149759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 149859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen break; 149959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen case eEncodingA1: 150059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Rm = Bits32(opcode, 3, 0); 150159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (Rm == 15) 150259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 150359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen break; 150459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen default: 150559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 150659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 15077bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 150859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 150959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (!success) 151059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 151159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 151259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Register dwarf_reg; 151359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 151459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen context.SetRegister (dwarf_reg); 151559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (!BXWritePC(context, target)) 151659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 151759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 151859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return true; 151959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen} 152059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 15210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset. 15220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate) 15232b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 15247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 15250d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 15260d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 15270d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 15280d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 15290d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15300d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 1531bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 15320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 15330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 15340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 15350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 15360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 15370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 15380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 15390d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 15400d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 15410d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15420d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 15430d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 15450d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15467bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1547e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t ip = ReadCoreReg (12, &success); 15480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 15490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 15500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 15510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 15520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 15530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 15540d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 15550d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 15560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 15570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t ip_offset = imm32; 15590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = ip - ip_offset; // the adjusted ip value 15600d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 15629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 15639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 15649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 15659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 15660d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 15680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 15690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 15710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 15720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset. 15740d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate) 15752b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 15767bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 15770d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 15780d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 15790d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 15800d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 15810d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15820d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 1583bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 15840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 15850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 15860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 15870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 15880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 15890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 15900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 15910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 15920d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 15930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15940d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 15950d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15967bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 15970d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1599e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 16000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 16010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 16030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 16040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 16050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 16060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 16070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 16080d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16090d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 16100d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t sp_offset = imm32; 16110d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = sp - sp_offset; // the adjusted stack pointer value 16120d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 16139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 16149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 16159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 16169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 16179bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 16180d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 16192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 16200d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 16220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 16230d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 16240d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 1625c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// This instruction subtracts an immediate value from the SP value, and writes 1626c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// the result to the destination register. 1627c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// 1628c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 16292b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 16307bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 16314c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{ 16324c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0 16334c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen // ARM pseudo code... 16344c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (ConditionPassed()) 16354c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 16364c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen EncodingSpecificOperations(); 1637bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 163815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if d == 15 then // Can only occur for ARM encoding 1639799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen ALUWritePC(result); // setflags is always FALSE here 16404c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen else 16414c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen R[d] = result; 16424c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if setflags then 16434c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.N = result<31>; 16444c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.Z = IsZeroBit(result); 16454c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.C = carry; 16464c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.V = overflow; 16474c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 16484c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif 16494c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 16504c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen bool success = false; 16517bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 16524c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 1653e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 16544c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (!success) 16554c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 1656c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 1657c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen uint32_t Rd; 1658c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen bool setflags; 16594c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen uint32_t imm32; 16604c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen switch (encoding) { 1661e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen case eEncodingT1: 1662c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = 13; 1663c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = false; 1664a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1665ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 166660c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT2: 1667c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 11, 8); 1668c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = BitIsSet(opcode, 20); 166960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1670c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 15 && setflags) 16717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateCMPImm(opcode, eEncodingT2); 1672c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 15 && !setflags) 1673c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen return false; 167460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 167560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT3: 1676c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 11, 8); 1677c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = false; 167860c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 167915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15) 168015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 168160c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 16824c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen case eEncodingA1: 1683c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 15, 12); 1684c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = BitIsSet(opcode, 20); 168560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 168615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 168715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 168815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 168915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 16904c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen break; 16914c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen default: 16924c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 16934c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 1694c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1695c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 16969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1697c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 13) 1698c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 16992b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 17002b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice // value gets passed down to context.SetImmediateSigned. 1701c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 17022b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetImmediateSigned (-imm64); // the stack pointer offset 1703c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen } 1704c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen else 1705c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 1706c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.type = EmulateInstruction::eContextImmediate; 1707c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.SetNoArgs (); 1708c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen } 1709c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 1710c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 17114c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 17124c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 17134c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return true; 17144c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen} 17154c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 171608c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP. 17172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 17187bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1719ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{ 1720ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0 1721ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen // ARM pseudo code... 1722ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (ConditionPassed()) 1723ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1724ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen EncodingSpecificOperations(); 1725ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1726ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen address = if index then offset_addr else R[n]; 1727ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1728ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if wback then R[n] = offset_addr; 1729ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1730ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif 1731ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 1732ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen bool success = false; 1733ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 17347bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1735ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 17362b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1737e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1738ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1739ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 174091d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 1741ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen uint32_t imm12; 17423e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 17433e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17443e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool index; 17453e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool add; 17463e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool wback; 1747ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen switch (encoding) { 1748ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen case eEncodingA1: 1749108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 1750108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen imm12 = Bits32(opcode, 11, 0); 17513e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice Rn = Bits32 (opcode, 19, 16); 17523e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17533e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 17543e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 17553e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17563e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice index = BitIsSet (opcode, 24); 17573e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice add = BitIsSet (opcode, 23); 17583e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 17593e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17603e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (wback && ((Rn == 15) || (Rn == Rt))) 17613e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 1762ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen break; 1763ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 1764ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1765ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 17663e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr_t offset_addr; 17673e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (add) 17683e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice offset_addr = sp + imm12; 17693e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice else 17703e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice offset_addr = sp - imm12; 17713e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17723e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr_t addr; 17733e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (index) 17743e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr = offset_addr; 17753e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice else 17763e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr = sp; 1777ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 17789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 17799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 17803e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice Register sp_reg; 17813e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 17823e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 178391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt != 15) 1784ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1785e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(Rt, &success); 1786ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1787ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1788cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1789ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1790ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1791ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen else 1792ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1793e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1794ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1795ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 17968d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemUWrite (context, addr, pc, addr_byte_size)) 1797ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1798ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1799ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 18003e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 18013e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (wback) 18023e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice { 18033e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 18043e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.SetImmediateSigned (addr - sp); 18053e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 18063e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 18073e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice } 1808ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1809ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return true; 1810ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen} 1811ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 181208c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack. 181308c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data. 18142b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 18157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1816799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{ 1817799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0 1818799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // ARM pseudo code... 1819799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (ConditionPassed()) 1820799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 1821799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1822799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = SP - imm32; 1823799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen SP = SP - imm32; 1824799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if single_regs then 1825799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1826799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = S[d+r]; address = address+4; 1827799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen else 1828799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1829799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // Store as two word-aligned words in the correct order for current endianness. 1830799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1831799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1832799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = address+8; 1833799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1834799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif 1835799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1836799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool success = false; 1837799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 18387bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1839799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 18402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1841e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1842799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1843799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1844799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool single_regs; 1845587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1846799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t imm32; // stack offset 1847799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t regs; // number of registers 1848799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen switch (encoding) { 1849799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT1: 1850799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA1: 1851799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = false; 1852bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1853799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1854799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // If UInt(imm8) is odd, see "FSTMX". 1855799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 1856799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1857799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1858799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1859799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 1860799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT2: 1861799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA2: 1862799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = true; 1863bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1864799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1865799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0); 1866799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1867799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1868799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1869799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 1870799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen default: 1871799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1872799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1873799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1874799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1875799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t sp_offset = imm32; 1876799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t addr = sp - sp_offset; 1877799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t i; 1878799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 18799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 18809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 18819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 18829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1883bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice Register sp_reg; 1884bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 1885bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice for (i=0; i<regs; ++i) 1886799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 1887bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice dwarf_reg.num = start_reg + d + i; 1888bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1889799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // uint64_t to accommodate 64-bit registers. 18909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1891799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1892799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1893cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 1894799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1895799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr += reg_byte_size; 1896799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1897799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1898799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 18999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 1900799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 19012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1902799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1903799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1904799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return true; 1905799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen} 1906799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1907587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack. 1908587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data. 1909587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool 19107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 1911587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{ 1912587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0 1913587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // ARM pseudo code... 1914587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (ConditionPassed()) 1915587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1916587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1917587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen address = SP; 1918587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen SP = SP + imm32; 1919587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if single_regs then 1920587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 1921587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen S[d+r] = MemA[address,4]; address = address+4; 1922587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen else 1923587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 1924587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1925587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Combine the word-aligned words in the correct order for current endianness. 1926587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1927587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1928587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif 1929587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1930587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool success = false; 1931587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 19327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1933587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1934587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen const uint32_t addr_byte_size = GetAddressByteSize(); 1935e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1936587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1937587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1938587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool single_regs; 1939587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1940587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t imm32; // stack offset 1941587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t regs; // number of registers 1942587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen switch (encoding) { 1943587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT1: 1944587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA1: 1945587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = false; 1946bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1947587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1948587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // If UInt(imm8) is odd, see "FLDMX". 1949587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 1950587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1951587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1952587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1953587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 1954587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT2: 1955587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA2: 1956587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = true; 1957bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1958587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1959587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0); 1960587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1961587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1962587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1963587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 1964587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen default: 1965587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1966587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1967587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1968587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1969587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t sp_offset = imm32; 1970587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t addr = sp; 1971587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t i; 1972587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint64_t data; // uint64_t to accomodate 64-bit registers. 1973587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 19749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 19759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 19769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 19779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1978bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice Register sp_reg; 1979bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 1980bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice for (i=0; i<regs; ++i) 1981587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1982bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice dwarf_reg.num = start_reg + d + i; 1983bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 1984cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, reg_byte_size, 0, &success); 1985587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1986587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 19879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1988587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1989587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr += reg_byte_size; 1990587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1991587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1992587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 19939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 1994587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1995587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1996587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1997587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1998587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return true; 1999587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen} 2000587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 2001b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI) 2002b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool 20037bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2004b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{ 2005b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0 2006b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // ARM pseudo code... 2007b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (ConditionPassed()) 2008b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 2009b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen EncodingSpecificOperations(); 2010b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen CallSupervisor(); 2011b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 2012b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif 2013b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 2014b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen bool success = false; 2015b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 20167bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 2017b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 2018e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 2019b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen addr_t lr; // next instruction address 2020b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!success) 2021b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2022b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t imm32; // the immediate constant 2023b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t mode; // ARM or Thumb mode 2024b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen switch (encoding) { 2025b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingT1: 2026b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = (pc + 2) | 1u; // return address 2027b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 7, 0); 2028b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeThumb; 2029b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 2030b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingA1: 2031b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = pc + 4; // return address 2032b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 23, 0); 2033b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeARM; 2034b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 2035b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen default: 2036b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2037b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 20389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 20399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 20409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextSupervisorCall; 20419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediate (mode, imm32); 2042b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2043b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2044b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 2045b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return true; 2046b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen} 2047b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 2048c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional. 2049c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool 20507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2051c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{ 2052c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0 2053c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // ARM pseudo code... 2054c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen EncodingSpecificOperations(); 2055c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen ITSTATE.IT<7:0> = firstcond:mask; 2056c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif 2057c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 2058c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.InitIT(Bits32(opcode, 7, 0)); 2059c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return true; 2060c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen} 2061c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 20623b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address. 20633b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool 20647bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 20653b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{ 20663b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0 20673b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // ARM pseudo code... 20683b620b38cd170c20ea607585021ab2ab50286943Johnny Chen if (ConditionPassed()) 20693b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 20703b620b38cd170c20ea607585021ab2ab50286943Johnny Chen EncodingSpecificOperations(); 20713b620b38cd170c20ea607585021ab2ab50286943Johnny Chen BranchWritePC(PC + imm32); 20723b620b38cd170c20ea607585021ab2ab50286943Johnny Chen } 20733b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif 20743b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 20753b620b38cd170c20ea607585021ab2ab50286943Johnny Chen bool success = false; 20763b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 20777bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 20789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 20799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 20809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2081e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 20829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!success) 20839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 208453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 20859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen int32_t imm32; // PC-relative offset 20869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen switch (encoding) { 20879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT1: 20889ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 20899ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2090e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 20919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 20929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 20939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT2: 20949ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2095e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 20969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 20979ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 20989ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT3: 20999ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 21009ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 2101bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 21029ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm6 = Bits32(opcode, 21, 16); 2103bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 2104bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 21059ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 210653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 21079ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<21>(imm21); 2108e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 21109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 21119ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT4: 21139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 2114bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 21159ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 2116bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 2117bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 21189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 21199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I1 = !(J1 ^ S); 21209ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I2 = !(J2 ^ S); 212153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 21229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 2123e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 21259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 21269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingA1: 21289ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2129e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 21319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 21329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 21339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 21349ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 21369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 21379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return true; 21393b620b38cd170c20ea607585021ab2ab50286943Johnny Chen} 21403b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 214153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 214253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value. They do not affect the condition flags. 214353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ 214453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool 21457bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 214653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{ 214753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0 214853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // ARM pseudo code... 214953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen EncodingSpecificOperations(); 215053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if nonzero ^ IsZero(R[n]) then 215153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen BranchWritePC(PC + imm32); 215253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif 215353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 215453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool success = false; 215553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 215653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // Read the register value from the operand register Rn. 2157e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 215853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 215953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 216053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 21619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 21629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2163e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 216453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 216553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 216653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 216753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 216853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm32; // PC-relative offset to branch forward 216953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool nonzero; 217053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen switch (encoding) { 217153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen case eEncodingT1: 2172bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 217353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen nonzero = BitIsSet(opcode, 11); 2174e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 217653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen break; 217753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen default: 217853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 217953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen } 218053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (nonzero ^ (reg_val == 0)) 218153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!BranchWritePC(context, target)) 218253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 218353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 218453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 218553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen} 218653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 218760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 218860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 218960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table. 219060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// 219160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 219260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 219360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table. 219460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH 219560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool 21967bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 219760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{ 219860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0 219960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // ARM pseudo code... 220060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(n); 220160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if is_tbh then 220260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 220360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen else 220460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+R[m], 1]); 220560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen BranchWritePC(PC + 2*halfwords); 220660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif 220760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 220860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool success = false; 220960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 221060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rn; // the base register which contains the address of the table of branch lengths 221160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 221260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool is_tbh; // true if table branch halfword 221360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen switch (encoding) { 221460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen case eEncodingT1: 221560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rn = Bits32(opcode, 19, 16); 221660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rm = Bits32(opcode, 3, 0); 221760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen is_tbh = BitIsSet(opcode, 4); 221860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (Rn == 13 || BadReg(Rm)) 221960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 222060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (InITBlock() && !LastInITBlock()) 222160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 222260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen break; 222360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen default: 222460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 222560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen } 222660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 222760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // Read the address of the table from the operand register Rn. 222860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // The PC can be used, in which case the table immediately follows this instruction. 2229e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t base = ReadCoreReg(Rm, &success); 223060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 223160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 223260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 223360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the table index 2234e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t index = ReadCoreReg(Rm, &success); 223560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 223660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 223760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 223860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the offsetted table address 223960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen addr_t addr = base + (is_tbh ? index*2 : index); 224060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 224160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // PC-relative offset to branch forward 224260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EmulateInstruction::Context context; 224360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextTableBranchReadMemory; 2244104c8b69863f229033d616245f56243ca51f1de9Johnny Chen uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 224560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 224660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 224760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 2248e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 224960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 225060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 225160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 225260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // target address 2253e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = pc + offset; 225460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextRelativeBranchImmediate; 225560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.SetModeAndImmediateSigned (eModeThumb, 4 + offset); 225660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 225760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!BranchWritePC(context, target)) 225860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 225960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 226060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return true; 226160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen} 226260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 2263dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// This instruction adds an immediate value to a register value, and writes the result to the destination register. 2264dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// It can optionally update the condition flags based on the result. 2265dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Ticebool 22667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2267dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice{ 2268dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#if 0 2269dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if ConditionPassed() then 2270dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice EncodingSpecificOperations(); 2271bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2272dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice R[d] = result; 2273dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if setflags then 2274dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.N = result<31>; 2275dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.Z = IsZeroBit(result); 2276dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.C = carry; 2277dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.V = overflow; 2278dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#endif 2279dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2280dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice bool success = false; 2281dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 22827bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 2283dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2284dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t d; 2285dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t n; 2286dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice bool setflags; 2287dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm32; 2288dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t carry_out; 2289dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2290dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //EncodingSpecificOperations(); 2291dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice switch (encoding) 2292dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2293dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT1: 2294dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2295dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 2, 0); 2296dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 5, 3); 2297dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = !InITBlock(); 2298dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = Bits32 (opcode, 8,6); 2299dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2300dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2301dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2302dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT2: 2303dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2304dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 10, 8); 2305dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 10, 8); 2306dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = !InITBlock(); 2307dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = Bits32 (opcode, 7, 0); 2308dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2309dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2310dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2311dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT3: 2312bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2313bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE ADD (SP plus immediate); 2314bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2315dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 11, 8); 2316dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 19, 16); 2317dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = BitIsSet (opcode, 20); 2318dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2319dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2320dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // if BadReg(d) || n == 15 then UNPREDICTABLE; 2321dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (BadReg (d) || (n == 15)) 2322dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2323dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2324dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2325dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2326dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT4: 2327dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2328bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE ADR; 2329bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE ADD (SP plus immediate); 2330dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2331dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 11, 8); 2332dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 19, 16); 2333dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = false; 2334dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t i = Bit32 (opcode, 26); 2335dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm3 = Bits32 (opcode, 14, 12); 2336dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm8 = Bits32 (opcode, 7, 0); 2337dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = (i << 11) | (imm3 << 8) | imm8; 2338dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2339dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // if BadReg(d) then UNPREDICTABLE; 2340dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (BadReg (d)) 2341dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2342dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2343dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2344dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2345dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice default: 2346dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2347dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2348dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2349dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2350dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (!success) 2351dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2352dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2353bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2354dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2355dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2356dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice Register reg_n; 2357dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2358dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2359dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice EmulateInstruction::Context context; 2360dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice context.type = eContextAddition; 2361dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice context.SetRegisterPlusOffset (reg_n, imm32); 2362dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2363dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //R[d] = result; 2364dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //if setflags then 2365dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.N = result<31>; 2366dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.Z = IsZeroBit(result); 2367dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.C = carry; 2368dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.V = overflow; 2369dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2370dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2371dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2372dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2373dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return true; 2374dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice} 2375dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 23768fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// This instruction adds an immediate value to a register value, and writes the result to the destination 23778fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// register. It can optionally update the condition flags based on the result. 23788fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chenbool 23797bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 23808fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen{ 23818fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#if 0 23828fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // ARM pseudo code... 23838fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if ConditionPassed() then 23848fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EncodingSpecificOperations(); 23858fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 23868fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if d == 15 then 23878fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen ALUWritePC(result); // setflags is always FALSE here 23888fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen else 23898fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen R[d] = result; 23908fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if setflags then 23918fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.N = result<31>; 23928fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.Z = IsZeroBit(result); 23938fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.C = carry; 23948fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.V = overflow; 23958fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#endif 23968fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 23978fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool success = false; 23988fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 23997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 24008fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 24018fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t Rd, Rn; 24028fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 24038fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool setflags; 24048fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen switch (encoding) 24058fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 24068fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 24078fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 24088fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 24098fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 24108fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 24118fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 24128fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen default: 24138fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 24148fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 24158fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24168fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // Read the first operand. 2417157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 24188fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!success) 24198fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 24208fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24218fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 24228fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24238fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EmulateInstruction::Context context; 24248fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen context.type = EmulateInstruction::eContextImmediate; 24258fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen context.SetNoArgs (); 24268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 24288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 24298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 24308fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return true; 24318fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen} 24328fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 2433d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result 2434d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 243526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 24367bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 243726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 243826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0 243926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // ARM pseudo code... 244026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if ConditionPassed() then 244126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen EncodingSpecificOperations(); 244226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 244326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 244426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if d == 15 then 244526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen ALUWritePC(result); // setflags is always FALSE here 244626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 244726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen R[d] = result; 244826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if setflags then 244926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.N = result<31>; 245026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.Z = IsZeroBit(result); 245126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.C = carry; 245226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.V = overflow; 245326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif 245426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 245526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen bool success = false; 245626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 24577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 245826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 245926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen uint32_t Rd, Rn, Rm; 2460d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen ARM_ShifterType shift_t; 2461d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2462ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen bool setflags; 246326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen switch (encoding) 246426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 2465d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen case eEncodingT1: 2466d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rd = Bits32(opcode, 2, 0); 2467d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rn = Bits32(opcode, 5, 3); 2468d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rm = Bits32(opcode, 8, 6); 2469d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen setflags = !InITBlock(); 2470d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2471d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 2472ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 247326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen case eEncodingT2: 2474bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 247526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen Rm = Bits32(opcode, 6, 3); 2476ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen setflags = false; 2477d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2478d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 247926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (Rn == 15 && Rm == 15) 248026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 2481d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 2482d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen return false; 248326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen break; 24848fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 24858fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 24868fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 24878fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rm = Bits32(opcode, 3, 0); 24888fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 24893dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 24908fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 249126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen default: 249226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 249326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 249426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 249526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the first operand. 2496157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 249726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 249826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 249926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 250026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the second operand. 2501157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 250226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 250326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 250426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 2505e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 25068fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 25079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 25089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 25098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = EmulateInstruction::eContextAddition; 25108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register op1_reg; 25118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register op2_reg; 25128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 25138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 25148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2515ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 251610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2517ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 251826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 251926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return true; 252026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 252126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 252234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (immediate) adds a register value and an immediate value. 252334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 252434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 25257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 252634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 252734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 252834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 252934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 253034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 253134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 253234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 253334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 253434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 253534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 253634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 253734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 253834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 253934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 254034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 254134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t imm32; // the immediate value to be compared with 254234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 254334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 2544078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2545078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2546078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15) 2547078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen return false; 2548ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 254934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 255034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 255134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 255234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 255334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 255434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 255534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 255634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from the operand register Rn. 255734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 255834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 255934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 256034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2561078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 256234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 256334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 256434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 256534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs (); 256634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 256734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 256834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 256934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 257034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 257134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 257234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (register) adds a register value and an optionally-shifted register value. 257334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 257434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 25757bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 257634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 257734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 257834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 257934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 258034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 258134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 258234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 258334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 258434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 258534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 258634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 258734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 258834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 258934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 259034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 259134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 259234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rm; // the second operand 259334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 259434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 259534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 259634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 259734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 2, 0); 259834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 5, 3); 259934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 260034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 260134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 260234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT2: 2603078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2604078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rm = Bits32(opcode, 3, 0); 26053dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 2606078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen // if n == 15 || BadReg(m) then UNPREDICTABLE; 2607078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15 || BadReg(Rm)) 260834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 260934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 261034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 261134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 261234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 26133dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 2614ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 261534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 261634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 261734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 261834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rn. 261934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 262034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 262134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 262234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 262334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rm. 262434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 262534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 262634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 262734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 262834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 2629078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 263034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 263134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 263234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 263334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs(); 263434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 263534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 263634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 263734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 263834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 263934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 264034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (immediate) subtracts an immediate value from a register value. 264134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2642d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool 26437bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2644d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{ 2645d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0 2646d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // ARM pseudo code... 2647d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if ConditionPassed() then 2648d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen EncodingSpecificOperations(); 2649d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2650d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.N = result<31>; 2651d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.Z = IsZeroBit(result); 2652d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.C = carry; 2653d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.V = overflow; 2654d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif 2655d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2656d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen bool success = false; 2657d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2658d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t Rn; // the first operand 2659d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t imm32; // the immediate value to be compared with 2660d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen switch (encoding) { 2661d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen case eEncodingT1: 2662d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen Rn = Bits32(opcode, 10, 8); 2663d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen imm32 = Bits32(opcode, 7, 0); 2664ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 2665078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen case eEncodingT2: 2666078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2667078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2668078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15) 2669078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen return false; 2670ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 267134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 267234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 267334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2674d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen break; 2675d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen default: 2676d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2677d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen } 2678d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // Read the register value from the operand register Rn. 2679e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 2680d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if (!success) 2681d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2682d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 268310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 268410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 26859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 26869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 26879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 268810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 268910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 269010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2691d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return true; 2692d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen} 2693d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 269434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (register) subtracts an optionally-shifted register value from a register value. 269534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2696e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool 26977bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2698e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{ 2699e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0 2700e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // ARM pseudo code... 2701e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if ConditionPassed() then 2702e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen EncodingSpecificOperations(); 2703e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2704e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2705e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.N = result<31>; 2706e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.Z = IsZeroBit(result); 2707e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.C = carry; 2708e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.V = overflow; 2709e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif 2710e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2711e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen bool success = false; 2712e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2713e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rn; // the first operand 2714e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rm; // the second operand 271534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 271634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2717e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen switch (encoding) { 2718e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT1: 2719e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bits32(opcode, 2, 0); 2720e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 5, 3); 272134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 272234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2723e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 2724e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT2: 2725e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2726e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 6, 3); 272734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 272834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2729e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn < 8 && Rm < 8) 2730e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2731e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn == 15 || Rm == 15) 2732e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2733e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 273434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 273534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 273634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 27373dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 2738ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 2739e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen default: 2740e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2741e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen } 2742e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rn. 274334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 2744e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2745e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 274634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2747e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rm. 274834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 2749e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2750e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2751e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 275234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 275334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 275410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 27559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 27569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 27579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs(); 275810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 275910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 276010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2761e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return true; 2762e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen} 2763e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 276482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 276582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. It can 276682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result. 276782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool 27687bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 276982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{ 277082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0 277182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // ARM pseudo code... 277282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if ConditionPassed() then 277382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EncodingSpecificOperations(); 277482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 277582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if d == 15 then // Can only occur for ARM encoding 277682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 277782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen else 277882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen R[d] = result; 277982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if setflags then 278082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.N = result<31>; 278182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.Z = IsZeroBit(result); 278282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.C = carry; 278382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // APSR.V unchanged 278482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif 278582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 27867bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_ASR); 278741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 278841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 278941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 279041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. 279141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update 279241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result. 279341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 27947bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 279541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 279641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 279741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 279841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 279941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 280041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 280141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 280241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 280341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 280441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 280541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 280641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 280741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 280841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 280941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_ASR); 281141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 281241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 281341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 281441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 281541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 281641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28177bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 281841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 281941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 282041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 282141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 282241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 282341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 282441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 282541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 282641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 282741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 282841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 282941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 283041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 283141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 283241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 283341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 283441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28357bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_LSL); 283641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 283741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 283841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits, 283941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 284041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 284141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 284241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28437bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 284441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 284541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 284641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 284741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 284841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 284941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 285041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 285141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 285241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 285341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 285441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 285541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 285641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 285741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 285841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28597bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_LSL); 286041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 286141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 286241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 286341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 286441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 286541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 286741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 286841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 286941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 287041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 287141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 287241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 287341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 287441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 287541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 287641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 287741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 287841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 287941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 288041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 288141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 288241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 288341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28847bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_LSR); 288541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 288641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 288741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits, 288841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 288941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 289041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 289141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28927bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 289341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 289441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 289541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 289641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 289741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 289841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 289941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 290041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 290141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 290241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 290341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 290441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 290541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 290641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 290741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 29087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_LSR); 290941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 291041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 2911eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 2912eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2913eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result. 2914eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 29157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 2916eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2917eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2918eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2919eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2920eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2921eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2922eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 2923eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 2924eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 2925eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2926eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2927eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2928eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2929eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2930eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2931eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2932eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 29337bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_ROR); 2934eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2935eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2936eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 2937eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2938eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 2939eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result. 2940eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 29417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 2942eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2943eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2944eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2945eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2946eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2947eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_n = UInt(R[m]<7:0>); 2948eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2949eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2950eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2951eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2952eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2953eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2954eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2955eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2956eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 29577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_ROR); 2958eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2959eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2960eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 2961eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31]. 2962eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// 2963eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result. 2964eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag. 2965eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 29667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 2967eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2968eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2969eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2970eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2971eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2972eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 2973eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 2974eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 2975eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 2976eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2977eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2978eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2979eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2980eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2981eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2982eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2983eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 29847bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_RRX); 2985eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2986eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 298741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 29887bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 298941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 2990bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice assert(shift_type == SRType_ASR 2991bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_LSL 2992bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_LSR 2993bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_ROR 2994bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_RRX); 299541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 299682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool success = false; 299782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 29987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 299982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 3000e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 3001e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the first operand register 3002e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t imm5; // encoding for the shift amount 300382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen uint32_t carry; // the carry bit after the shift operation 300482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool setflags; 3005eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 3006eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Special case handling! 3007eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) -- Encoding T1 30087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton ARMEncoding use_encoding = encoding; 30097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3010eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 3011eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3012eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // have the same decoding of bit fields as the other Thumb2 shift operations. 30137bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton use_encoding = eEncodingT2; 3014eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen } 3015eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 30167bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton switch (use_encoding) { 301782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT1: 3018eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Due to the above special case handling! 3019eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen assert(shift_type != SRType_ROR); 3020eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 302182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 2, 0); 302282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 5, 3); 302382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = !InITBlock(); 302482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 10, 6); 302582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 302682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT2: 3027eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.141 RRX 3028eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen assert(shift_type != SRType_RRX); 3029eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 303082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 11, 8); 303182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 303282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 303382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 303482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (BadReg(Rd) || BadReg(Rm)) 303582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 303682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 303782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingA1: 303882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 15, 12); 303982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 304082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 304182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 11, 7); 304282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 304382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen default: 304482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 304582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 304682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3047eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) 3048eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if (shift_type == SRType_ROR && imm5 == 0) 3049eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_type = SRType_RRX; 3050eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 305182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // Get the first operand. 3052e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rm, &success); 305382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (!success) 305482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 305582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3056eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Decode the shift amount if not RRX. 3057eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 305882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3059e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 306082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 306182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // The context specifies that an immediate is to be moved into Rd. 306282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EmulateInstruction::Context context; 306382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 306482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.SetNoArgs (); 306582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 306610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3067ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 306882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 306982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return true; 307082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen} 307182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3072e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool 30737bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3074e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{ 307541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 3076e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3077e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool success = false; 3078e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 30797bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3080e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 3081e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 3082e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rn; // the first operand register 3083e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3084e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t carry; // the carry bit after the shift operation 3085e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool setflags; 3086e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen switch (encoding) { 3087e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT1: 3088e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 2, 0); 3089e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Rd; 3090e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 5, 3); 3091e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = !InITBlock(); 3092e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3093e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT2: 3094e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 11, 8); 3095e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 19, 16); 3096e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 3, 0); 3097e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 3098e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3099e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3100e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3101e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingA1: 3102e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 15, 12); 3103e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 3, 0); 3104e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 11, 8); 3105e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 3106e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (Rd == 15 || Rn == 15 || Rm == 15) 3107e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3108e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3109e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen default: 3110e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3111e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 3112e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3113e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the first operand. 3114e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rn, &success); 3115e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 3116e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3117e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the Rm register content. 3118e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadCoreReg (Rm, &success); 3119e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 3120e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3121e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3122e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the shift amount. 3123e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t amt = Bits32(val, 7, 0); 3124e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3125e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 3126e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3127e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // The context specifies that an immediate is to be moved into Rd. 3128e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen EmulateInstruction::Context context; 3129e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.type = EmulateInstruction::eContextImmediate; 3130e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.SetNoArgs (); 3131e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 313210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3133e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3134e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 3135e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return true; 3136e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen} 3137e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3138b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an 3139713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register. Optionally the address just above the highest of those locations 3140b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register. 3141b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool 31427bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3143b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{ 3144b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0 3145b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // ARM pseudo code... 3146b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ConditionPassed() 3147b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3148b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice address = R[n]; 3149b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3150b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for i = 0 to 14 3151b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<i> == '1' then 3152b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice R[i] = MemA[address, 4]; address = address + 4; 3153b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<15> == '1' then 3154b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice LoadWritePC (MemA[address, 4]); 3155b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3156b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3157b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3158b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3159b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif 3160b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3161b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool success = false; 3162b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 31637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3164b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3165b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t n; 3166b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t registers = 0; 3167b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool wback; 3168b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3169b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice switch (encoding) 3170b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3171b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT1: 3172bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3173b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 10, 8); 3174b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 7, 0); 3175b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3176b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsClear (registers, n); 3177b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 3178b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitCount(registers) < 1) 3179b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3180b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3181b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT2: 3182bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101' then SEE POP; 3183bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3184b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 3185b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 3186b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is zero. 3187b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 3188b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3189bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3190b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 3191b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 2) 3192b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3193b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3194b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3195bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3196098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3197b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3198b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3199bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 3200b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback 3201b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice && BitIsSet (registers, n)) 3202b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3203b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3204b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3205b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingA1: 3206b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 3207b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 3208b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 3209b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 3210b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 1)) 3211b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3212b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3213b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice default: 3214b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3215b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3216b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3217b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice int32_t offset = 0; 3218b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3219b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3220b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 322185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 32229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 32239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 32259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 32269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3227b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3228b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for (int i = 0; i < 14; ++i) 3229b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3230b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, i)) 3231b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 323285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3234b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && (n == 13)) // Pop Instruction 3235b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 3236b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3237b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[i] = MemA [address, 4]; address = address + 4; 3238cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3239b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3240b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3241b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3242b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3243b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3244b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3245b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice offset += addr_byte_size; 3246b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3247b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3248b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3249b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, 15)) 3250b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3251b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //LoadWritePC (MemA [address, 4]); 325285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3254cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3255b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3256b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3257e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3258668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3259b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3260b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3261b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3262b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsClear (registers, n)) 3263b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3264fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // R[n] = R[n] + 4 * BitCount (registers) 3265fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = addr_byte_size * BitCount (registers); 3266fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 32679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3268b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3269b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3270b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3271b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3272b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsSet (registers, n)) 3273b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[n] bits(32) UNKNOWN; 3274713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3275b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3276b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return true; 3277b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice} 3278713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3279bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3280bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// The consecutive memory locations end at this address and the address just below the lowest of those locations 3281bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// can optionally be written back to the base register. 3282713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 32837bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3284713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 3285713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0 3286713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // ARM pseudo code... 3287713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ConditionPassed() then 3288713c2665a27096b68f3f8956222375354f1292f8Caroline Tice EncodingSpecificOperations(); 3289713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 3290713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3291713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for i = 0 to 14 3292bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 3293713c2665a27096b68f3f8956222375354f1292f8Caroline Tice R[i] = MemA[address,4]; address = address + 4; 3294713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3295bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 3296713c2665a27096b68f3f8956222375354f1292f8Caroline Tice LoadWritePC(MemA[address,4]); 3297713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3298bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3299bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3300713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif 3301713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3302713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool success = false; 3303713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 33047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3305713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3306713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t n; 3307713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t registers = 0; 3308713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool wback; 3309713c2665a27096b68f3f8956222375354f1292f8Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3310713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3311713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // EncodingSpecificOperations(); 3312713c2665a27096b68f3f8956222375354f1292f8Caroline Tice switch (encoding) 3313713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3314713c2665a27096b68f3f8956222375354f1292f8Caroline Tice case eEncodingA1: 3315bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3316713c2665a27096b68f3f8956222375354f1292f8Caroline Tice n = Bits32 (opcode, 19, 16); 3317713c2665a27096b68f3f8956222375354f1292f8Caroline Tice registers = Bits32 (opcode, 15, 0); 3318713c2665a27096b68f3f8956222375354f1292f8Caroline Tice wback = BitIsSet (opcode, 21); 3319b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3320713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3321713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 3322713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3323713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3324713c2665a27096b68f3f8956222375354f1292f8Caroline Tice break; 3325713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3326713c2665a27096b68f3f8956222375354f1292f8Caroline Tice default: 3327713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3328713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3329713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 3330713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3331713c2665a27096b68f3f8956222375354f1292f8Caroline Tice int32_t offset = 0; 3332bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 3333713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3334713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3335713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3336713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3337bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3338713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 33399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 33409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 33419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 33429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 33439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3344713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3345713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // for i = 0 to 14 3346713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for (int i = 0; i < 14; ++i) 3347713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3348bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 3349713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, i)) 3350713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3351713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // R[i] = MemA[address,4]; address = address + 4; 3352bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3353cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3354713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3355713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3356713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3357713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3358713c2665a27096b68f3f8956222375354f1292f8Caroline Tice offset += addr_byte_size; 3359713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3360713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3361713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3362bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 3363713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // LoadWritePC(MemA[address,4]); 3364713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, 15)) 3365713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 33669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3367cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3368713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3369713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 337044c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen // In ARMv5T and above, this is an interworking branch. 3371668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3372713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3373713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3374713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3375bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3376713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsClear (registers, n)) 3377713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3378713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3379713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3380fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3381fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3382fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 33839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3384bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 3385713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3386713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3387713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3388713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3389bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3390713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsSet (registers, n)) 3391713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3392713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3393713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 3394713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 3395713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3396713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3397713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3398713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register. 33990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool 34007bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 34010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{ 34020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0 34030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // ARM pseudo code... 34040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ConditionPassed() then 34050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 34060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice address = R[n] - 4*BitCount(registers); 34070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34080b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for i = 0 to 14 3409bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 34100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice R[i] = MemA[address,4]; address = address + 4; 3411bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 34120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice LoadWritePC(MemA[address,4]); 34130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3414bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3415bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 34160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif 34170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool success = false; 34190b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34207bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 34210b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t n; 34230b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t registers = 0; 34240b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool wback; 34250b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 34260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice switch (encoding) 34270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34280b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingT1: 3429bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 34300b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 34310b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 3432b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is a zero. 34330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 34340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3435bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 34360b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) 34370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitCount (registers) < 2) 34380b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 34390b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34400b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3441bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3442098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 34430b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34440b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3445bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 34460b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 34470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 34500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingA1: 3452bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 34530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 34540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 34550b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 34560b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 34580b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 34590b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 34620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice default: 34640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 34660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3467713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers); 3468713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 34690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice int32_t offset = 0; 3470bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3471713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3472713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3473713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3474713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3475bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)); 34769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 34779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 34789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 34799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3480bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 34810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for (int i = 0; i < 14; ++i) 34830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, i)) 34850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34860b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 3487bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3488cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 34890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 34900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 34930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice offset += addr_byte_size; 34960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 34970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 34980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3499bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 35000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // LoadWritePC(MemA[address,4]); 35010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, 15)) 35020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 35039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3504cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 35050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 35060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3507e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3508668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 35090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 35100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 35110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3512bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 35130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsClear (registers, n)) 35140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 35150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 35160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3517fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3518fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3519fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 35209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3521bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 35220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 35230b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 35240b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 35250b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3526bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 35270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 3528713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 35290b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 35300b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return true; 35310b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice} 353285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3533713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3534713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3535713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register. 353685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool 35377bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 353885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{ 353985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0 354085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ConditionPassed() then 354185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice EncodingSpecificOperations(); 354285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice address = R[n] + 4; 354385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 354485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for i = 0 to 14 3545bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 354685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice R[i] = MemA[address,4]; address = address + 4; 3547bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 354885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice LoadWritePC(MemA[address,4]); 354985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3550bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3551bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 355285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif 355385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 355485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool success = false; 355585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 35567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 355785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 355885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t n; 355985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t registers = 0; 356085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool wback; 356185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 356285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice switch (encoding) 356385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 356485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice case eEncodingA1: 3565bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 356685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice n = Bits32 (opcode, 19, 16); 356785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice registers = Bits32 (opcode, 15, 0); 356885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice wback = BitIsSet (opcode, 21); 356985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 357085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 357185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 357285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 357385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 357485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice break; 357585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice default: 357685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 357785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 357885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // address = R[n] + 4; 357985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 358085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice int32_t offset = 0; 3581bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3582713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3583713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3584713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3585713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3586bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn + addr_byte_size; 358785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 35889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 35899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 35909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 35919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 35929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 359385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 359485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for (int i = 0; i < 14; ++i) 359585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 359685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, i)) 359785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 359885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 359985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3600bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3601cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 360285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 360385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 360485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 360585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 360685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 360785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 360885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice offset += addr_byte_size; 360985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 361085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 361185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3612bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 361385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // LoadWritePC(MemA[address,4]); 361485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, 15)) 361585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 36169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3617cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 361885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 361985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3620e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3621668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 362285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 362385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 362485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3625bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 362685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsClear (registers, n)) 362785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 362885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 362985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3630fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3631fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3632fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 36339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3634bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 363585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 363685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 363785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 363885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3639bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 364085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsSet (registers, n)) 3641713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 364285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 364385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return true; 364485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice} 36450b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3646ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and 3647ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register. 3648ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb) 3649ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 36507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3651ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 3652ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0 3653ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // ARM pseudo code... 3654ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (ConditionPassed()) 3655ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3656ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3657ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3658ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = if index then offset_addr else R[n]; 3659ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen data = MemU[address,4]; 3660ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if wback then R[n] = offset_addr; 3661ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if t == 15 then 3662ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3663ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen elsif UnalignedSupport() || address<1:0> = '00' then 3664ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen R[t] = data; 3665ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3666ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3667ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif 3668ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3669ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool success = false; 3670ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 36717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3672ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3673ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rt; // the destination register 3674ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rn; // the base register 3675ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t imm32; // the immediate offset used to form the address 3676ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t offset_addr; // the offset address 3677ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t address; // the calculated address 3678ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t data; // the literal data value from memory load 3679ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool add, index, wback; 3680ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen switch (encoding) { 3681baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT1: 3682baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32(opcode, 5, 3); 3683baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32(opcode, 2, 0); 3684baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3685baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE 3686baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3687baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3688baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3689baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3690baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3691baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3692baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT2: 3693bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3694baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 10, 8); 3695baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = 13; 3696baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 3697baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3698baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 3699baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3700baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3701baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3702baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3703baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3704baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3705baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT3: 3706bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 3707baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3708baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 15, 12); 3709baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32 (opcode, 19, 16); 3710baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 11, 0); 3711baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3712baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 3713baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3714baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3715baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3716baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3717baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3718baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3719baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3720baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3721baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3722baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3723baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT4: 3724bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 3725bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3726bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3727bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 3728baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3729baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3730baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3731baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3732baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 15, 12); 3733baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32 (opcode, 19, 16); 3734baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 7, 0); 3735baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3736bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3737baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = BitIsSet (opcode, 10); 3738baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = BitIsSet (opcode, 9); 3739baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = BitIsSet (opcode, 8); 3740baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3741baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3742baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3743baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3744baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3745baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3746baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3747baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice default: 3748baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3749ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3750baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice uint32_t base = ReadCoreReg (Rn, &success); 3751ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3752ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3753ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (add) 3754ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base + imm32; 3755ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3756ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base - imm32; 3757ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3758ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = (index ? offset_addr : base); 3759ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3760baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Register base_reg; 3761baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 3762ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (wback) 3763ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 37649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context ctx; 3765baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3766baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 37679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 3768ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3769ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3770ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3771ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3772ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Prepare to write to the Rt register. 37739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 3774baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice context.type = EmulateInstruction::eContextRegisterLoad; 3775baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3776ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3777ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Read memory from the address. 3778cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 3779ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3780ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3781ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3782ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Rt == 15) 3783ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3784ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Bits32(address, 1, 0) == 0) 3785ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3786668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3787ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3788ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3789ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3790ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3791ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3792ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3793ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3794ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3795ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3796ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3797ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3798baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice WriteBits32Unknown (Rt); 3799ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3800ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return true; 3801ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 3802ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3803af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3804af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start at this address, and teh address just above the last 3805af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 3806fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 38077bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 3808fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 3809fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0 3810fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ConditionPassed() then 3811fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3812fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = R[n]; 3813fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3814fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for i = 0 to 14 3815bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 3816fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 3817fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3818fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 3819fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = R[i]; 3820fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = address + 4; 3821fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3822bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then // Only possible for encoding A1 3823fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = PCStoreValue(); 3824fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 3825fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif 3826fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3827fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool success = false; 3828fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 38297bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3830fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3831fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t n; 3832fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t registers = 0; 3833fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool wback; 3834fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3835fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3836fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3837fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice switch (encoding) 3838fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3839fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT1: 3840bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 3841fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 10, 8); 3842fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 7, 0); 3843b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3844fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = true; 3845fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3846fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 3847fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitCount (registers) < 1) 3848fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3849fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3850fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3851fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3852fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT2: 3853bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 3854fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 3855fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 3856b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3857fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 3858fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3859fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3860fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 2)) 3861fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3862fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3863bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 3864fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback && BitIsSet (registers, n)) 3865fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3866fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3867fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3868fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3869fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingA1: 3870bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3871fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 3872fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 3873fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 3874fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3875fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3876fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 3877fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3878fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3879fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3880fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3881fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice default: 3882fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3883fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3884fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3885fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = R[n]; 3886fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = 0; 3887fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3888fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3889fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3890fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 38919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 38929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 38939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register base_reg; 38949bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3895fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3896fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // for i = 0 to 14 3897bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice int lowest_set_bit = 14; 3898fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for (int i = 0; i < 14; ++i) 3899fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3900bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 3901fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, i)) 3902fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3903fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (i < lowest_set_bit) 3904fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice lowest_set_bit = i; 3905fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 3906fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 3907fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3908fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice WriteBits32UnknownToMemory (address + offset); 3909fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 3910fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3911fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = R[i]; 3912fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3913fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3914fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3915fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 39169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register data_reg; 39179bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 39189bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3919cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3920fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3921fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3922fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3923fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = address + 4; 3924fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset += addr_byte_size; 3925fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3926fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3927fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3928bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then // Only possible for encoding A1 3929fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = PCStoreValue(); 3930fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, 15)) 3931fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 39329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register pc_reg; 39339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 39349bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 39358d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 3936fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3937fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3938fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 39398d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 3940fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3941fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3942fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3943fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 3944fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback) 3945fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3946fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3947fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 39489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3949fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr_t data = address + offset; 3950fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3951fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3952fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3953fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3954fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 3955fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 3956fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3957af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 3958af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3959af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 39601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool 39617bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 39621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{ 39631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0 39641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ConditionPassed() then 39651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EncodingSpecificOperations(); 39661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 39671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for i = 0 to 14 3969bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 39701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 39711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; 39721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 39731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = R[i]; 39741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = address + 4; 39751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 3976bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 39771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = PCStoreValue(); 39781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 39801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif 39811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool success = false; 39831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39847bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 39851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 39861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t n; 39871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t registers = 0; 39881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool wback; 39891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 39901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // EncodingSpecificOperations(); 39921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice switch (encoding) 39931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 39941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice case eEncodingA1: 3995bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 39961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice n = Bits32 (opcode, 19, 16); 39971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice registers = Bits32 (opcode, 15, 0); 39981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice wback = BitIsSet (opcode, 21); 39991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 40011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 40021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice break; 40041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice default: 40051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40071511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 40091511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice int32_t offset = 0; 4010bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 40111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 40121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40131511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4014bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 40151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EmulateInstruction::Context context; 40171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 40181511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register base_reg; 40191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 40201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40211511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // for i = 0 to 14 4022bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice int lowest_bit_set = 14; 40231511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for (int i = 0; i < 14; ++i) 40241511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4025bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 40261511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, i)) 40271511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 40281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (i < lowest_bit_set) 40291511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice lowest_bit_set = i; 40301511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice //if i == n && wback && i != LowestSetBit(registers) then 40311511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((i == n) && wback && (i != lowest_bit_set)) 40321511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; 40331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice WriteBits32UnknownToMemory (address + offset); 40341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 40351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 40361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = R[i]; 40371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 40381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 40391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40411511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register data_reg; 40421511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4043bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4044cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 40451511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40461511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40471511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40481511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = address + 4; 40491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice offset += addr_byte_size; 40501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40521511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4053bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 40541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = PCStoreValue(); 40551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, 15)) 40561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 40571511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register pc_reg; 40581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 40591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 40608d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 40611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 40621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40648d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 40651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 40691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (wback) 40701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4071af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 40721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 40731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetImmediateSigned (offset); 4074bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 40751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 40761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return true; 40801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice} 40811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4082af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4083af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end just below this address, and the address of the first of 4084af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register. 4085b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool 40867bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4087b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{ 4088b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0 4089b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ConditionPassed() then 4090b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4091b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = R[n] - 4*BitCount(registers); 4092b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4093b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for i = 0 to 14 4094bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4095b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 4096b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4097b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 4098b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = R[i]; 4099b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = address + 4; 4100b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4101bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then // Only possible for encoding A1 4102b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = PCStoreValue(); 4103b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4104b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 4105b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif 4106b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4107b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4108b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool success = false; 4109b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 41107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4111b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4112b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t n; 4113b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t registers = 0; 4114b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool wback; 4115b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4116b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4117b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4118b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice switch (encoding) 4119b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4120b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingT1: 4121bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101' then SEE PUSH; 4122b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4123b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4124b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See PUSH 4125b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4126bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4127b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 4128b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 4129b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4130b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 4131b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4132b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 2) 4133b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4134bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 4135b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback && BitIsSet (registers, n)) 4136b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4137b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 4138b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4139b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingA1: 4140bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH; 4141b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4142b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4143b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See Push 4144b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4145bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4146b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 4147b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 4148b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 4149b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4150b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 1) 4151b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4152b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 4153b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4154b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice default: 4155b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4156b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4157b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4158b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = R[n] - 4*BitCount(registers); 4159b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4160b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice int32_t offset = 0; 4161bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4162b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4163b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4164b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4165bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4166b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4167b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EmulateInstruction::Context context; 4168b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4169b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register base_reg; 4170b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4171b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4172b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // for i = 0 to 14 4173bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice uint32_t lowest_set_bit = 14; 4174b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for (int i = 0; i < 14; ++i) 4175b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4176bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4177b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, i)) 4178b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4179b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (i < lowest_set_bit) 4180b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice lowest_set_bit = i; 4181b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4182b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4183b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4184b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice WriteBits32UnknownToMemory (address + offset); 4185b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 4186b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4187b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = R[i]; 4188b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4189b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4190b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4191b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4192b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register data_reg; 4193b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4194bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4195cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4196b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4197b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4198b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4199b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = address + 4; 4200b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset += addr_byte_size; 4201b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4202b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4203b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4204bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then // Only possible for encoding A1 4205b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = PCStoreValue(); 4206b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, 15)) 4207b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4208b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register pc_reg; 4209b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 4210b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 42118d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4212b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4213b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4214b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 42158d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4216b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4217b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4218b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4219b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 4220b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback) 4221b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4222af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 4223af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 4224af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetImmediateSigned (offset); 4225bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 4226af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4227af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4228af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4229af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4230af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return true; 4231af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice} 4232af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4233af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4234af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start just above this address, and the address of the last 4235af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 4236af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool 42377bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4238af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{ 4239af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0 4240af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ConditionPassed() then 4241af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EncodingSpecificOperations(); 4242af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = R[n] + 4; 4243af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4244af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for i = 0 to 14 4245bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4246af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if i == n && wback && i != LowestSetBit(registers) then 4247af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = bits(32) UNKNOWN; 4248af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 4249af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = R[i]; 4250af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = address + 4; 4251af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4252bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 4253af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = PCStoreValue(); 4254af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4255af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 4256af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif 4257af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4258af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool success = false; 4259af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 42607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4261af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4262af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t n; 4263af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t registers = 0; 4264af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool wback; 4265af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4266af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4267af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // EncodingSpecificOperations(); 4268af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice switch (encoding) 4269af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4270af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice case eEncodingA1: 4271bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4272af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice n = Bits32 (opcode, 19, 16); 4273af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice registers = Bits32 (opcode, 15, 0); 4274af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice wback = BitIsSet (opcode, 21); 4275af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4276af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4277af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((n == 15) && (BitCount (registers) < 1)) 4278af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4279af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice break; 4280af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice default: 4281af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4282af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4283af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = R[n] + 4; 4284af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4285af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice int32_t offset = 0; 4286bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 4287af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4288af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4289af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4290bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn + addr_byte_size; 4291af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4292af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EmulateInstruction::Context context; 4293af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4294af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register base_reg; 4295af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4296af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4297af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t lowest_set_bit = 14; 4298af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // for i = 0 to 14 4299af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for (int i = 0; i < 14; ++i) 4300af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4301bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4302af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, i)) 4303af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4304af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (i < lowest_set_bit) 4305af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice lowest_set_bit = i; 4306af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4307af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4308af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = bits(32) UNKNOWN; 4309af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice WriteBits32UnknownToMemory (address + offset); 4310af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // else 4311af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 4312af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4313af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = R[i]; 4314af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4315af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4316af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4317af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4318af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register data_reg; 4319af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4320bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4321cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4322af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4323af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4324af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4325af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = address + 4; 4326af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset += addr_byte_size; 4327af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4328af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4329af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4330bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 4331af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = PCStoreValue(); 4332af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, 15)) 4333af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4334af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register pc_reg; 4335af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 4336af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 43378d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4338af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4339af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4340af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 43418d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4342af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4343af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4344af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4345af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 4346af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (wback) 4347af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4348b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset = addr_byte_size * BitCount (registers); 4349b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 4350b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetImmediateSigned (offset); 4351bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 4352b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4353b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4354b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4355b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4356b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return true; 4357b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice} 43587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 43607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 43617fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool 43627bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 43637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{ 43647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0 43657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ConditionPassed() then 43667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 43677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 43687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = if index then offset_addr else R[n]; 4369bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<1:0> == '00' then 43707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = R[t]; 43717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else // Can only occur before ARMv7 43727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = bits(32) UNKNOWN; 43737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if wback then R[n] = offset_addr; 43747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif 43757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool success = false; 43777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 43797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 43807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 43817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t t; 43837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t n; 43847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t imm32; 43857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool index; 43867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool add; 43877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool wback; 43887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 43897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice switch (encoding) 43907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 43917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT1: 4392bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 43937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 2, 0); 43947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 5, 3); 43957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 10, 6) << 2; 43967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 43987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 43997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = false; 44007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 44017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT2: 4404bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 44057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 10, 8); 44067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = 13; 44077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 44087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 44107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 44117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 44127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 44137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT3: 4416bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 44177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 44187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 44217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 44227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 44237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 11, 0); 44247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 44267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 44277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 44287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 44297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 then UNPREDICTABLE; 44317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (t == 15) 44327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT4: 4436bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE STRT; 4437bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4438bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 44397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((Bits32 (opcode, 19, 16) == 15) 44407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 44417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 44447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 44457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 44467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0); 44477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4448bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 44497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = BitIsSet (opcode, 10); 44507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = BitIsSet (opcode, 9); 44517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = BitIsSet (opcode, 8); 44527fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 44547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((t == 15) || (wback && (n == t))) 44557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice default: 44597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 44617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t offset_addr; 44637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t address; 4464b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 44657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4466baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice uint32_t base_address = ReadCoreReg (n, &success); 44677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 44687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (add) 44717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address + imm32; 44727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 44737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address - imm32; 44747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // address = if index then offset_addr else R[n]; 44767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (index) 44777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = offset_addr; 44787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 44797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = base_address; 44807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EmulateInstruction::Context context; 44827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterStore; 44837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice Register base_reg; 44847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 44857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4486bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<1:0> == '00' then 44877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 44887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 44897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = R[t]; 44907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 44917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 44927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice Register data_reg; 44957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 44967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice int32_t offset = address - base_address; 44977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4498cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 44997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 45007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 45027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 45037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = bits(32) UNKNOWN; 45047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice WriteBits32UnknownToMemory (address); 45057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if wback then R[n] = offset_addr; 45087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (wback) 45097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 45107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterLoad; 45117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetAddress (offset_addr); 45127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 45137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 45147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return true; 45177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice} 4518af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 45193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 45203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory. The offset register value can optionally be shifted. 45213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool 45227bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 45233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{ 45243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0 45253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ConditionPassed() then 45263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 45273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 45283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 45293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = if index then offset_addr else R[n]; 45303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if t == 15 then // Only possible for encoding A1 45313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = PCStoreValue(); 45323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 45333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = R[t]; 4534bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 45353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = data; 45363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else // Can only occur before ARMv7 45373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = bits(32) UNKNOWN; 45383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if wback then R[n] = offset_addr; 45393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif 45403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool success = false; 45423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45437bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 45443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 45453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 45463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t t; 45483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t n; 45493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t m; 45503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice ARM_ShifterType shift_t; 45513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t shift_n; 45523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool index; 45533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool add; 45543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool wback; 45553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 45573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice switch (encoding) 45583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 45593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT1: 45603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 45613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 45623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 2, 0); 45633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 5, 3); 45643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 8, 6); 45653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 45673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 45683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 45693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 45703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 45723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 45733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = 0; 45743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 45753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT2: 4577bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 45783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (Bits32 (opcode, 19, 16) == 15) 45793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 45803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 45823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 45833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 45843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 45853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 45873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 45883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 45893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 45903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 45923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 45933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = Bits32 (opcode, 5, 4); 45943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 || BadReg(m) then UNPREDICTABLE; 45963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ((t == 15) || (BadReg (m))) 45973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 45983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 45993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingA1: 46013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 4602bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE STRT; 46033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 46043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 46053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 46063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 46073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4608bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 46093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = BitIsSet (opcode, 24); 46103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = BitIsSet (opcode, 23); 46113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 46123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 46143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t typ = Bits32 (opcode, 6, 5); 46153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 46163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = DecodeImmShift(typ, imm5, shift_t); 46173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if m == 15 then UNPREDICTABLE; 46193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (m == 15) 46203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 46233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback && ((n == 15) || (n == t))) 46243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 46273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 46283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice default: 46293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 46313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t offset_addr; 46333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t address; 46343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice int32_t offset = 0; 46353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 46373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 46383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 46413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 46423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4645e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen offset = Shift (Rm_data, shift_t, shift_n, APSR_C); 46463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 46483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (add) 46493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address + offset; 46503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address - offset; 46523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // address = if index then offset_addr else R[n]; 46543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (index) 46553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = offset_addr; 46563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = base_address; 46583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t data; 46603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 then // Only possible for encoding A1 46613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (t == 15) 46623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = PCStoreValue(); 46638d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice data = ReadCoreReg (PC_REG, &success); 46643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = R[t]; 46663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 46673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 46693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EmulateInstruction::Context context; 46723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterStore; 46733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4674bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 46753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (UnalignedSupport () 46763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || (BitIsClear (address, 1) && BitIsClear (address, 0)) 46773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || CurrentInstrSet() == eModeARM) 46783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 46793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = data; 46803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice Register base_reg; 46823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 46833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice Register data_reg; 46853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 46863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4688cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 46893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 46923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = bits(32) UNKNOWN; 46943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice WriteBits32UnknownToMemory (address); 46953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback then R[n] = offset_addr; 46973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback) 46983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 46993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterLoad; 47003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetAddress (offset_addr); 47013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 47023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 47033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 47043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 47063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return true; 47073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice} 470873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 470973a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool 47107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 471173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{ 471273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0 471373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ConditionPassed() then 471473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 471573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 471673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = if index then offset_addr else R[n]; 471773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice MemU[address,1] = R[t]<7:0>; 471873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if wback then R[n] = offset_addr; 471973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif 472073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 472173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 472273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool success = false; 472373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 47247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 472573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 472673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t t; 472773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t n; 472873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t imm32; 472973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool index; 473073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool add; 473173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool wback; 473273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 473373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice switch (encoding) 473473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 473573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT1: 473673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 473773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 2, 0); 473873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 5, 3); 473973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 10, 6); 474073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 474173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 474273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 474373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 474473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 474573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 474673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 474773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT2: 4748bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 474973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 475073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 475173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 475273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 475373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 475473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 475573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 11, 0); 475673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 475773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 475873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 475973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 476073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 476173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 476273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) then UNPREDICTABLE; 476373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (BadReg (t)) 476473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 476573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 476673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 476773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT3: 4768bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4769bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 477073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 477173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 477273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 477373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 477473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 477573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 477673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 7, 0); 477773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4778bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 477973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = BitIsSet (opcode, 10); 478073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = BitIsSet (opcode, 9); 478173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = BitIsSet (opcode, 8); 478273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 478373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 478473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ((BadReg (t)) || (wback && (n == t))) 478573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 478673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 478773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 478873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice default: 478973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 479073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 479173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 479273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t offset_addr; 479373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t address; 479473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 479573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 479673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 479773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 479873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 479973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (add) 480073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address + imm32; 480173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 480273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address - imm32; 480373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 480473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // address = if index then offset_addr else R[n]; 480573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (index) 480673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = offset_addr; 480773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 480873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = base_address; 480973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4810cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice // MemU[address,1] = R[t]<7:0> 481173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice Register base_reg; 481273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 481373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 481473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice Register data_reg; 481573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 481673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 481773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EmulateInstruction::Context context; 481873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterStore; 481973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 482073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 482173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 482273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 482373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 482473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 482573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data = Bits32 (data, 7, 0); 482673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4827cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, 1)) 482873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 482973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 483073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if wback then R[n] = offset_addr; 483173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (wback) 483273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 483373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterLoad; 483473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetAddress (offset_addr); 483573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 483673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 483773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 483873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 483973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 484073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 484173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return true; 484273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice} 48438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// STRH (register) calculates an address from a base register value and an offset register value, and stores a 48458ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 48468ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Ticebool 48477bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 48488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice{ 48498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#if 0 48508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if ConditionPassed() then 48518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 48528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 48538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 48548ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = if index then offset_addr else R[n]; 4855bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> == '0' then 48568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice MemU[address,2] = R[t]<15:0>; 48578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else // Can only occur before ARMv7 48588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice MemU[address,2] = bits(16) UNKNOWN; 48598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if wback then R[n] = offset_addr; 48608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#endif 48618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool success = false; 48638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48647bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 48658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 48668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t t; 48678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t n; 48688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t m; 48698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool index; 48708ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool add; 48718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool wback; 48728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice ARM_ShifterType shift_t; 48738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t shift_n; 48748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 48768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice switch (encoding) 48778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 48788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingT1: 48798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 48808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 48818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 2, 0); 48828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 5, 3); 48838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 8, 6); 48848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48858ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 48868ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = true; 48878ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = true; 48888ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = false; 48898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 48918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 48928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = 0; 48938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 48958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingT2: 4897bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 48988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 48998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 15, 12); 49008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 19, 16); 49018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 3, 0); 49028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (n == 15) 49038ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 49068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = true; 49078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = true; 49088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = false; 49098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 49118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 49128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = Bits32 (opcode, 5, 4); 49138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 49158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (BadReg (t) || BadReg (m)) 49168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49178ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 49198ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49208ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingA1: 4921bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE STRHT; 49228ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 49238ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 15, 12); 49248ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 19, 16); 49258ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 3, 0); 49268ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 4927bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 49288ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = BitIsSet (opcode, 24); 49298ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = BitIsSet (opcode, 23); 49308ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 49318ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49328ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 49338ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 49348ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = 0; 49358ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49368ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 49378ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if ((t == 15) || (m == 15)) 49388ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49398ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49408ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 49418ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (wback && ((n == 15) || (n == t))) 49428ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 49458ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49468ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice default: 49478ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 49498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 49518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 49528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49548ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 49558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 49568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 49598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 49608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 49628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice addr_t offset_addr; 49638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (add) 49648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = Rn + offset; 49658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else 49668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = Rn - offset; 49678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // address = if index then offset_addr else R[n]; 49698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice addr_t address; 49708ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (index) 49718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = offset_addr; 49728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else 49738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = Rn; 49748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EmulateInstruction::Context context; 49768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextRegisterStore; 49778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register base_reg; 49788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 49798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register offset_reg; 49808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 49818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 4982bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> == '0' then 49838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 49848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 49858ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // MemU[address,2] = R[t]<15:0>; 49868ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rt = ReadCoreReg (t, &success); 49878ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 49888ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EmulateInstruction::Context context; 49918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextRegisterStore; 49928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register base_reg; 49938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 49948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register offset_reg; 49958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 49968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register data_reg; 49978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 49988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 49998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 50018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 50028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50038ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else // Can only occur before ARMv7 50048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 50058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // MemU[address,2] = bits(16) UNKNOWN; 50068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if wback then R[n] = offset_addr; 50098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (wback) 50108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 50118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextAdjustBaseRegister; 50128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetAddress (offset_addr); 50138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 50148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 50158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50178ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return true; 50198ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice} 50203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 5021157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5022157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// and writes the result to the destination register. It can optionally update the condition flags 5023157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// based on the result. 5024157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 50257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5026157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 5027157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 5028157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 5029157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 5030157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 5031157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5032157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 5033157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5034157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 5035157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 5036157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 5037157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 5038157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 5039157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 5040157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 5041157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 5042157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5043157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 5044157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 50457bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5046157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5047157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn; 5048157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5049157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 5050157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 5051157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5052157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 5053157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 5054157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5055157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 5056157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5057157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 5058157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5059157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5060157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 5061157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 5062157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5063157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 5064157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5065157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5066157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 5067157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5068157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5069157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 5070157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5071157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5072157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5073157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 5074157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 5075157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5076157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5077157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5078157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5079157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5080157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 5081157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5082157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 5083157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5084157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5085157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5086157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5087157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 5088157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 5089157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5090157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5091157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// register value, and writes the result to the destination register. It can optionally update the 5092157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// condition flags based on the result. 5093157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 50947bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5095157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 5096157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 5097157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 5098157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 5099157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 5100157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5101157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5102157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 5103157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5104157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 5105157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 5106157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 5107157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 5108157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 5109157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 5110157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 5111157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 5112157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5113157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 5114157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 51157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5116157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5117157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn, Rm; 5118157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ARM_ShifterType shift_t; 5119157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5120157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 5121157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 5122157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5123157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 5124157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5125157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 5, 3); 5126157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = !InITBlock(); 5127157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_t = SRType_LSL; 5128157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = 0; 5129ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 5130157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT2: 5131157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 5132157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5133157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 5134157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 51353dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5136157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5137157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5138157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5139157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 5140157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 5141157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5142157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 5143157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 51443dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 5145157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5146157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 5147157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5148157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5149157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 5150157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5151157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5152157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5153157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 5154157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 5155157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5156157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5157157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5158157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the second operand. 5159157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val2 = ReadCoreReg(Rm, &success); 5160157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5161157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5162157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5163157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 5164157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5165157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5166157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 5167157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5168157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 5169157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5170157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5171157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5172157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5173157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 5174157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 5175157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5176a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// This instruction adds an immediate value to the PC value to form a PC-relative address, 5177a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// and writes the result to the destination register. 5178a695f958db37c102d480a9c0780abec262ba8332Johnny Chenbool 51797bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5180a695f958db37c102d480a9c0780abec262ba8332Johnny Chen{ 5181a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#if 0 5182a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // ARM pseudo code... 5183a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if ConditionPassed() then 5184a695f958db37c102d480a9c0780abec262ba8332Johnny Chen EncodingSpecificOperations(); 5185a695f958db37c102d480a9c0780abec262ba8332Johnny Chen result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5186a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if d == 15 then // Can only occur for ARM encodings 5187a695f958db37c102d480a9c0780abec262ba8332Johnny Chen ALUWritePC(result); 5188a695f958db37c102d480a9c0780abec262ba8332Johnny Chen else 5189a695f958db37c102d480a9c0780abec262ba8332Johnny Chen R[d] = result; 5190a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#endif 5191a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5192a695f958db37c102d480a9c0780abec262ba8332Johnny Chen bool success = false; 5193a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 51947bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5195a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 5196a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t Rd; 5197a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5198a695f958db37c102d480a9c0780abec262ba8332Johnny Chen bool add; 5199a695f958db37c102d480a9c0780abec262ba8332Johnny Chen switch (encoding) 5200a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 5201a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT1: 5202a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 10, 8); 5203a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5204a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5205a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT2: 5206a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT3: 5207a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 11, 8); 5208a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5209a695f958db37c102d480a9c0780abec262ba8332Johnny Chen add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5210a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (BadReg(Rd)) 5211a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5212a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5213a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingA1: 5214a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingA2: 5215a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 15, 12); 5216a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5217a695f958db37c102d480a9c0780abec262ba8332Johnny Chen add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5218a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5219a695f958db37c102d480a9c0780abec262ba8332Johnny Chen default: 5220a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5221a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 5222a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5223a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // Read the PC value. 5224a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t pc = ReadCoreReg(PC_REG, &success); 5225a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!success) 5226a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5227a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5228a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5229a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5230a695f958db37c102d480a9c0780abec262ba8332Johnny Chen EmulateInstruction::Context context; 5231a695f958db37c102d480a9c0780abec262ba8332Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5232a695f958db37c102d480a9c0780abec262ba8332Johnny Chen context.SetNoArgs (); 5233a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5234a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!WriteCoreReg(context, result, Rd)) 5235a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5236a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 5237a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return true; 5238a695f958db37c102d480a9c0780abec262ba8332Johnny Chen} 5239a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5240e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5241e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 5242e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 52437bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5244e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 5245e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 5246e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 5247e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 5248e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 5249e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND imm32; 5250e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 5251e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5252e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 5253e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 5254e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 5255e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 5256e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 5257e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 5258e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 5259e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 5260e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5261e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 5262e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 52637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5264e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5265e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn; 5266e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5267e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 5268e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5269e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 5270e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5271e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 5272e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 5273e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5274e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 5275e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5276de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (immediate); 5277e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 52787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTSTImm(opcode, eEncodingT1); 5279e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5280e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5281e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5282e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 5283e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 5284e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5285e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 5286e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5287e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5288e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 5289e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5290e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5291e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 5292e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5293e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5294e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5295e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 5296157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5297e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5298e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5299e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5300e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & imm32; 5301e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5302e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 5303e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 5304e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 5305e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5306e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5307e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5308e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5309e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 5310e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 5311e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5312e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5313e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags 5314e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// based on the result. 5315e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 53167bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5317e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 5318e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 5319e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 5320e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 5321e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 5322e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5323e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND shifted; 5324e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 5325e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5326e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 5327e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 5328e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 5329e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 5330e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 5331e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 5332e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 5333e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 5334e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5335e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 5336e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 53377bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5338e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5339e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn, Rm; 5340e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ARM_ShifterType shift_t; 5341e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5342e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 5343e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; 5344e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 5345e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5346e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 5347e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5348e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 5, 3); 5349e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = !InITBlock(); 5350e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_t = SRType_LSL; 5351e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_n = 0; 5352ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 5353e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT2: 5354e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 5355e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5356e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 5357e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 53583dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5359de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (register); 5360e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 53617bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTSTReg(opcode, eEncodingT2); 5362e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5363e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5364e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5365e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 5366e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 5367e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5368e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 5369e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 53703dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 5371e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5372e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 5373e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5374e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5375e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 5376e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5377e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5378e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5379e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 5380157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5381e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5382e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5383e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5384e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the second operand. 5385157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 5386e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5387e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5388e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5389e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 5390e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & shifted; 5391e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5392e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 5393e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 5394e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 5395e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5396e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5397e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5398e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5399e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 5400e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 5401e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5402b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5403b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// immediate value, and writes the result to the destination register. It can optionally update the 5404b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// condition flags based on the result. 5405b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool 54067bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5407b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{ 5408b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0 5409b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // ARM pseudo code... 5410b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if ConditionPassed() then 5411b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EncodingSpecificOperations(); 5412b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen result = R[n] AND NOT(imm32); 5413b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if d == 15 then // Can only occur for ARM encoding 5414b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5415b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen else 5416b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen R[d] = result; 5417b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if setflags then 5418b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.N = result<31>; 5419b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.Z = IsZeroBit(result); 5420b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.C = carry; 5421b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // APSR.V unchanged 5422b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif 5423b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5424b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool success = false; 5425b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 54267bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5427b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5428b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t Rd, Rn; 5429b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5430b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool setflags; 5431b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5432b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen switch (encoding) 5433b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5434b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT1: 5435b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 11, 8); 5436b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5437b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5438b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5439b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 5440b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5441b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5442b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingA1: 5443b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 15, 12); 5444b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5445b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5446b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5447bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5448b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5449b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (Rd == 15 && setflags) 5450b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5451b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5452b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen default: 5453b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5454b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5455b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5456b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the first operand. 5457b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5458b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5459b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5460b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5461b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t result = val1 & ~imm32; 5462b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5463b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EmulateInstruction::Context context; 5464b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5465b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.SetNoArgs (); 5466b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5467b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5468b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5469b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5470b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return true; 5471b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen} 5472b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5473b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5474b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// optionally-shifted register value, and writes the result to the destination register. 5475b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// It can optionally update the condition flags based on the result. 5476b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool 54777bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5478b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{ 5479b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0 5480b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // ARM pseudo code... 5481b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if ConditionPassed() then 5482b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EncodingSpecificOperations(); 5483b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5484b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen result = R[n] AND NOT(shifted); 5485b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if d == 15 then // Can only occur for ARM encoding 5486b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5487b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen else 5488b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen R[d] = result; 5489b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if setflags then 5490b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.N = result<31>; 5491b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.Z = IsZeroBit(result); 5492b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.C = carry; 5493b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // APSR.V unchanged 5494b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif 5495b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5496b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool success = false; 5497b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 54987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5499b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5500b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t Rd, Rn, Rm; 5501b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ARM_ShifterType shift_t; 5502b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5503b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool setflags; 5504b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t carry; 5505b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen switch (encoding) 5506b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5507b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT1: 5508b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5509b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 5, 3); 5510b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = !InITBlock(); 5511b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_t = SRType_LSL; 5512b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = 0; 5513b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5514b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT2: 5515b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 11, 8); 5516b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5517b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 3, 0); 5518b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5519b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5520b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5521b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5522b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5523b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingA1: 5524b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 15, 12); 5525b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5526b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 3, 0); 5527b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5528b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 5529bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5530b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5531b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (Rd == 15 && setflags) 5532b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5533b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5534b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen default: 5535b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5536b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5537b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5538b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the first operand. 5539b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5540b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5541b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5542b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5543b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the second operand. 5544b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 5545b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5546b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5547b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5548b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 5549b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t result = val1 & ~shifted; 5550b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5551b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EmulateInstruction::Context context; 5552b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5553b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.SetNoArgs (); 5554b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5555b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5556b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5557b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5558b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return true; 5559b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen} 5560b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 55614d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5562e92b27c9262fd185359e6e2184b20d08953485f4Johnny Chen// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 55634d729c559d039181f250e0e3cd444fa73638f26fCaroline Ticebool 55647bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 55654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice{ 55664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#if 0 55674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if ConditionPassed() then 55684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EncodingSpecificOperations(); 55694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 55704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = if index then offset_addr else R[n]; 55714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = MemU[address,4]; 55724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if wback then R[n] = offset_addr; 55734d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if t == 15 then 5574bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5575bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 55764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = data; 55774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else // Can only apply before ARMv7 55784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 55794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#endif 55804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool success = false; 55824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55837bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 55844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 55854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 55864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t t; 55884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t n; 55894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t imm32; 55904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool index; 55914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool add; 55924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool wback; 55934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice switch (encoding) 55954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 55964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice case eEncodingA1: 5597bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 5598bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRT; 5599bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 56004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 56014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice t = Bits32 (opcode, 15, 12); 56024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice n = Bits32 (opcode, 19, 16); 56034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice imm32 = Bits32 (opcode, 11, 0); 56044d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5605bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5606bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice index = BitIsSet (opcode, 24); 5607bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice add = BitIsSet (opcode, 23); 5608bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 56094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback && n == t then UNPREDICTABLE; 56114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback && (n == t)) 56124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice break; 56154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice default: 56174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56204d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t address; 56214d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t offset_addr; 56228d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice addr_t base_address = ReadCoreReg (n, &success); 56234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 56244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 56274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (add) 56288d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice offset_addr = base_address + imm32; 56294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = base_address - imm32; 56314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // address = if index then offset_addr else R[n]; 56334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (index) 56344d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = offset_addr; 56354d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56364d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = base_address; 56374d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56384d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // data = MemU[address,4]; 56394d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56404d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice Register base_reg; 56414d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 56424d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56434d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EmulateInstruction::Context context; 56444d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56454d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 56464d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56474d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 56484d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 56494d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56504d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56514d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback then R[n] = offset_addr; 56524d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback) 56534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56544d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextAdjustBaseRegister; 56554d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetAddress (offset_addr); 56564d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 56574d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56584d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if t == 15 then 56614d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (t == 15) 56624d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 5663bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 56644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 56654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // LoadWritePC (data); 56674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 56694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice LoadWritePC (context, data); 56704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56734d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 5674bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // elsif UnalignedSupport() || address<1:0> = '00' then 56754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 56764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = data; 56784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 56804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 56814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // else // Can only apply before ARMv7 56844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 56874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = ROR (data, Bits32 (address, 1, 0)); 56884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetImmediate (data); 56904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 56914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return true; 56964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice} 56974d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5698fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5699fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5700fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Ticebool 57017bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5702fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice{ 5703fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#if 0 5704fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ConditionPassed() then 5705fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5706fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 5707fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5708fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = if index then offset_addr else R[n]; 5709fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = MemU[address,4]; 5710fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if wback then R[n] = offset_addr; 5711fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if t == 15 then 5712bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5713bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 5714fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = data; 5715fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 5716fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if CurrentInstrSet() == InstrSet_ARM then 5717fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 5718fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5719fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = bits(32) UNKNOWN; 5720fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#endif 5721fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5722fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool success = false; 5723fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 57247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5725fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5726fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 5727fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5728fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t t; 5729fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t n; 5730fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t m; 5731fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool index; 5732fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool add; 5733fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool wback; 5734fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice ARM_ShifterType shift_t; 5735fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t shift_n; 5736fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5737fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice switch (encoding) 5738fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5739fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT1: 5740fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5741fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5742fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 2, 0); 5743fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 5, 3); 5744fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 8, 6); 5745fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5746fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5747fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5748fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5749fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5750fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5751fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 5752fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5753fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = 0; 5754fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5755fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5756fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5757fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT2: 5758bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 5759fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5760fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5761fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5762fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5763fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5764fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5765fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5766fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5767fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5768fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5769fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5770fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5771fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = Bits32 (opcode, 5, 4); 5772fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5773fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if BadReg(m) then UNPREDICTABLE; 5774fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BadReg (m)) 5775fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5776fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5777fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5778fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ((t == 15) && InITBlock() && !LastInITBlock()) 5779fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5780fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5781fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5782fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5783fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingA1: 5784fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5785bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRT; 5786fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5787fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5788fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5789fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5790fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5791bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5792fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = BitIsSet (opcode, 24); 5793fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = BitIsSet (opcode, 23); 5794fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5795fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5796fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5797fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 5798fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 5799fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 5800fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5801fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if m == 15 then UNPREDICTABLE; 5802fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (m == 15) 5803fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5804fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5805fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5806fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback && ((n == 15) || (n == t))) 5807fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5808fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5809fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5810fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5811fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5812fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice default: 5813fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5814fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5815fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5816fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5817fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5818fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5819fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5820fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5821fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5822fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5823fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5824fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t offset_addr; 5825fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t address; 5826fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5827fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 5828b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C)); 5829fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5830fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5831fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (add) 5832fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn + offset; 5833fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5834fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn - offset; 5835fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5836fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // address = if index then offset_addr else R[n]; 5837fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (index) 5838fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = offset_addr; 5839fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5840fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = Rn; 5841fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5842fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // data = MemU[address,4]; 5843fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice Register base_reg; 5844fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5845fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5846fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EmulateInstruction::Context context; 5847fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5848fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5849fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5850fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5851fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5852fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5853fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5854fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback then R[n] = offset_addr; 5855fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback) 5856fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5857fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextAdjustBaseRegister; 5858fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetAddress (offset_addr); 5859fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5860fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5861fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5862fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5863fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 then 5864fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (t == 15) 5865fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5866bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5867fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5868fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5869fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5870fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5871fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice LoadWritePC (context, data); 5872fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5873fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5874fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5875fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5876bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // elsif UnalignedSupport() || address<1:0> = '00' then 5877fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5878fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5879fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = data; 5880fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5881fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5882fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5883fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5884fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5885fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 5886fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5887fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ARM then 5888fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (CurrentInstrSet () == eModeARM) 5889fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5890fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 5891fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = ROR (data, Bits32 (address, 1, 0)); 5892fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5893fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetImmediate (data); 5894fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5895fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5896fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5897fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5898fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5899fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = bits(32) UNKNOWN; 5900fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice WriteBits32Unknown (t); 5901fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5902fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5903fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5904fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return true; 5905fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice} 590621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 590721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice// LDRB (immediate, Thumb) 590821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Ticebool 59097bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 591021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice{ 591121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#if 0 591221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if ConditionPassed() then 591321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 591421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 591521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = if index then offset_addr else R[n]; 591621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 591721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if wback then R[n] = offset_addr; 591821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#endif 591921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 592021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool success = false; 592121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 59227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 592321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 592421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t t; 592521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t n; 592621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t imm32; 592721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool index; 592821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool add; 592921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool wback; 593021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 593121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 593221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice switch (encoding) 593321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 593421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT1: 593521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 593621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 2, 0); 593721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 5, 3); 593821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 10, 6); 593921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 594021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 594121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 594221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 594321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback= false; 594421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 594521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 594621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 594721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT2: 5948bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 5949bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 595021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 595121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 595221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 595321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 11, 0); 595421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 595521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 595621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 595721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 595821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = false; 595921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 596021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if t == 13 then UNPREDICTABLE; 596121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (t == 13) 596221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 596321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 596421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 596521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 596621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT3: 5967bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 5968bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 5969bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 5970bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 597121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 597221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 597321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 597421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 597521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 597621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 597721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 7, 0); 597821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 5979bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 598021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = BitIsSet (opcode, 10); 598121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = BitIsSet (opcode, 9); 598221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = BitIsSet (opcode, 8); 598321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 598421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 598521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BadReg (t) || (wback && (n == t))) 598621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 598721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 598821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 598921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 599021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice default: 599121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 599221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 599321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 599421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 599521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 599621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 599721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 599821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t address; 599921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t offset_addr; 600021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 600121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 600221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (add) 600321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn + imm32; 600421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 600521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn - imm32; 600621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 600721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // address = if index then offset_addr else R[n]; 600821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (index) 600921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = offset_addr; 601021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 601121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = Rn; 601221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 601321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 601421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice Register base_reg; 601521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice Register data_reg; 601621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 601721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 601821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 601921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EmulateInstruction::Context context; 602021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextRegisterLoad; 602121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 602221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 602321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 602421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 602521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 602621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 602721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 602821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 602921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 603021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if wback then R[n] = offset_addr; 603121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (wback) 603221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 603321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextAdjustBaseRegister; 603421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetAddress (offset_addr); 603521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 603621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 603721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 603821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 603921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return true; 604021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice} 6041f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6042f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6043f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// zero-extends it to form a 32-bit word and writes it to a register. 6044f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Ticebool 60457bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6046f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice{ 6047f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#if 0 6048f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if ConditionPassed() then 6049f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6050f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice base = Align(PC,4); 6051f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = if add then (base + imm32) else (base - imm32); 6052f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 6053f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#endif 6054f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6055f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool success = false; 6056f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 60577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6058f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 6059f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t t; 6060f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t imm32; 6061f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool add; 6062f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice switch (encoding) 6063f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 6064f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingT1: 6065bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6066bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6067f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 6068f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6069f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 6070f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6071f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 13 then UNPREDICTABLE; 6072f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 13) 6073f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6074f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6075f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 6076f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6077f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingA1: 6078bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6079f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 6080f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6081f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 6082f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6083f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 15 then UNPREDICTABLE; 6084f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 15) 6085f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6086f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 6087f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6088f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice default: 6089f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6090f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 6091f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6092f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // base = Align(PC,4); 60938d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6094f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 6095f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6096f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6097f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t base = AlignPC (pc_val); 6098f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6099f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice addr_t address; 6100f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // address = if add then (base + imm32) else (base - imm32); 6101f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (add) 6102f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base + imm32; 6103f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice else 6104f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base - imm32; 6105f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6106f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 6107f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EmulateInstruction::Context context; 6108f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.type = eContextRelativeBranchImmediate; 6109f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.SetImmediate (address - base); 6110f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6111f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 6112f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 6113f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6114f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6115f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6116f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6117f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 6118f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return true; 6119f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice} 612030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 612130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 612230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 612330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// optionally be shifted. 612430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Ticebool 61257bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 612630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice{ 612730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#if 0 612830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ConditionPassed() then 612930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 613030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 613130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 613230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = if index then offset_addr else R[n]; 613330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice R[t] = ZeroExtend(MemU[address,1],32); 613430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if wback then R[n] = offset_addr; 613530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#endif 613630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 613730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool success = false; 613830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 61397bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 614030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 614130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t t; 614230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t n; 614330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t m; 614430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool index; 614530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool add; 614630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool wback; 614730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice ARM_ShifterType shift_t; 614830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t shift_n; 614930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 615030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 615130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice switch (encoding) 615230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 615330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT1: 615430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 615530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 2, 0); 615630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 5, 3); 615730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 8, 6); 615830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 615930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 616030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 616130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 616230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 616330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 616430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 616530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 616630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = 0; 616730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 616830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 616930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT2: 6170bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6171bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 617230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 617330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 617430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 617530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 617630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 617730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 617830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 617930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 618030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 618130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 618230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 618330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 618430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = Bits32 (opcode, 5, 4); 618530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 618630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 618730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 13) || BadReg (m)) 618830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 618930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 619030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 619130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingA1: 619230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 6193bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRBT; 619430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 619530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 619630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 619730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 619830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 6199bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 620030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = BitIsSet (opcode, 24); 620130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = BitIsSet (opcode, 23); 620230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 620330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 620430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 620530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 620630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 620730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 620830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 620930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 621030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 15) || (m == 15)) 621130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 621230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 621330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 621430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback && ((n == 15) || (n == t))) 621530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 621630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 621730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 621830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 621930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice default: 622030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 622130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 622230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 622330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset_addr; 622430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t address; 622530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 622630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 622730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 622830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 622930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 623030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 623130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 623230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 623330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 623430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 623530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 623630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 623730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 623830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (add) 623930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn + offset; 624030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 624130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn - offset; 624230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 624330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // address = if index then offset_addr else R[n]; 624430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (index) 624530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = offset_addr; 624630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 624730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = Rn; 624830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 624930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // R[t] = ZeroExtend(MemU[address,1],32); 625030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice Register base_reg; 625130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 625230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 625330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EmulateInstruction::Context context; 625430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextRegisterLoad; 625530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 625630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 625730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 625830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 625930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 626030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 626130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 626230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 626330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 626430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback then R[n] = offset_addr; 626530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback) 626630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 626730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextAdjustBaseRegister; 626830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetAddress (offset_addr); 626930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 627030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 627130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 627230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 627330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return true; 627430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice} 62750491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62760491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 62770491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 62780491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// post-indexed, or pre-indexed addressing. 62790491b3b75e1b045ab548f77fd1f76035522debdeCaroline Ticebool 62807bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 62810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice{ 62820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#if 0 62830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if ConditionPassed() then 62840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 62850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 62860491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = if index then offset_addr else R[n]; 62870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice data = MemU[address,2]; 62880491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if wback then R[n] = offset_addr; 6289bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 62900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice R[t] = ZeroExtend(data, 32); 62910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else // Can only apply before ARMv7 62920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice R[t] = bits(32) UNKNOWN; 62930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#endif 62940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62950491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool success = false; 62970491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 62990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 63000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t t; 63010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t n; 63020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t imm32; 63030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool index; 63040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool add; 63050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool wback; 63060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 63080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice switch (encoding) 63090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 63100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT1: 6311bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 63120491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 2, 0); 63130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 5, 3); 63140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 10, 6) << 1; 63150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 63170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = true; 63180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = true; 63190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = false; 63200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 63220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT2: 6324bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 6325bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 63260491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 63270491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 15, 12); 63280491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 19, 16); 63290491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 11, 0); 63300491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63310491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 63320491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = true; 63330491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = true; 63340491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = false; 63350491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63360491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if t == 13 then UNPREDICTABLE; 63370491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (t == 13) 63380491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63390491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 63400491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63410491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT3: 6342bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 6343bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6344bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6345bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 63460491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 63470491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63480491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63490491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 63500491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 15, 12); 63510491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 19, 16); 63520491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 7, 0); 63530491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 6354bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 63550491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = BitIsSet (opcode, 10); 63560491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = BitIsSet (opcode, 9); 63570491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = BitIsSet (opcode, 8); 63580491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63590491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 63600491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (BadReg (t) || (wback && (n == t))) 63610491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63620491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 63630491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63640491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice default: 63650491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63660491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 63670491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63680491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 63690491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 63700491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!success) 63710491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63720491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63730491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice addr_t offset_addr; 63740491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice addr_t address; 63750491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63760491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (add) 63770491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = Rn + imm32; 63780491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else 63790491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = Rn - imm32; 63800491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // address = if index then offset_addr else R[n]; 63820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (index) 63830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = offset_addr; 63840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else 63850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = Rn; 63860491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // data = MemU[address,2]; 63880491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice Register base_reg; 63890491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 63900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice EmulateInstruction::Context context; 63920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextRegisterLoad; 63930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 63940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63950491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 63960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!success) 63970491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if wback then R[n] = offset_addr; 64000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (wback) 64010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 64020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextAdjustBaseRegister; 64030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetAddress (offset_addr); 64040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 64050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 64060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 6408bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 64090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (UnalignedSupport () || BitIsClear (address, 0)) 64100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 64110491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // R[t] = ZeroExtend(data, 32); 64120491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextRegisterLoad; 64130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 64140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 64150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 64160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else // Can only apply before ARMv7 64180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 64190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // R[t] = bits(32) UNKNOWN; 64200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice WriteBits32Unknown (t); 64210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return true; 64240491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice} 6425fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6426952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6427952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// zero-extends it to form a 32-bit word, and writes it to a register. 6428952b53892191222c56003cd60d8a4a71c4384aa7Caroline Ticebool 64297bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6430952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice{ 6431952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#if 0 6432952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if ConditionPassed() then 6433952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6434952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice base = Align(PC,4); 6435952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = if add then (base + imm32) else (base - imm32); 6436952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice data = MemU[address,2]; 6437bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 6438952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice R[t] = ZeroExtend(data, 32); 6439952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else // Can only apply before ARMv7 6440952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice R[t] = bits(32) UNKNOWN; 6441952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#endif 64420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6443952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice bool success = false; 6444952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 64457bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6446952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6447952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t t; 6448952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm32; 6449952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice bool add; 6450952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6451952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6452952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice switch (encoding) 6453952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6454952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice case eEncodingT1: 6455bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 6456bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6457952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice t = Bits32 (opcode, 15, 12); 6458952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6459952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice add = BitIsSet (opcode, 23); 6460952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6461952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // if t == 13 then UNPREDICTABLE; 6462952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (t == 13) 6463952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6464952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6465952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice break; 6466952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6467952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice case eEncodingA1: 6468952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6469952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 6470952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 6471952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6472bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6473952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice t = Bits32 (opcode, 15, 12); 647440b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 6475952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice add = BitIsSet (opcode, 23); 6476952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6477952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // if t == 15 then UNPREDICTABLE; 6478952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (t == 15) 6479952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6480952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice break; 6481952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6482952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6483952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice default: 6484952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6485952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6486952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6487952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // base = Align(PC,4); 64888d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6489952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!success) 6490952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6491952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6492952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice addr_t base = AlignPC (pc_value); 6493952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice addr_t address; 6494952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6495952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // address = if add then (base + imm32) else (base - imm32); 6496952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (add) 6497952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = base + imm32; 6498952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else 6499952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = base - imm32; 6500952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6501952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // data = MemU[address,2]; 6502952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice Register base_reg; 6503952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 6504952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6505952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice EmulateInstruction::Context context; 6506952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.type = eContextRegisterLoad; 6507952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 6508952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6509952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 6510952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!success) 6511952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6512952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6513952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6514bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 6515952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (UnalignedSupport () || BitIsClear (address, 0)) 6516952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6517952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // R[t] = ZeroExtend(data, 32); 6518952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.type = eContextRegisterLoad; 6519952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 6520952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6521952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6522952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6523952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6524952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else // Can only apply before ARMv7 6525952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6526952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // R[t] = bits(32) UNKNOWN; 6527952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice WriteBits32Unknown (t); 6528952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6529952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6530952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return true; 6531952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice} 6532952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 65330e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 65340e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 65350e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// be shifted left by 0, 1, 2, or 3 bits. 65360e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Ticebool 65377bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 65380e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice{ 65390e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#if 0 65400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ConditionPassed() then 65410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 65420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 65430e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 65440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = if index then offset_addr else R[n]; 65450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice data = MemU[address,2]; 65460e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if wback then R[n] = offset_addr; 6547bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 65480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice R[t] = ZeroExtend(data, 32); 65490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else // Can only apply before ARMv7 65500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice R[t] = bits(32) UNKNOWN; 65510e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#endif 65520e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65530e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool success = false; 65540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 65560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 65570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t t; 65580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t n; 65590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t m; 65600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool index; 65610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool add; 65620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool wback; 65630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice ARM_ShifterType shift_t; 65640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t shift_n; 65650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 65670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice switch (encoding) 65680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 65690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingT1: 65700e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 65710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 65720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 2, 0); 65730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 5, 3); 65740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 8, 6); 65750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 65770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = true; 65780e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = true; 65790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = false; 65800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 65820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 65830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = 0; 65840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 65860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65870e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingT2: 6588bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 6589bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 65900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 65910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 15, 12); 65920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 19, 16); 65930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 3, 0); 65940e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65950e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 65960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = true; 65970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = true; 65980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = false; 65990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 66010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 66020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = Bits32 (opcode, 5, 4); 66030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 66050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ((t == 13) || BadReg (m)) 66060e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66070e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 66080e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66090e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingA1: 6610bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRHT; 66110e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 66120e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 15, 12); 66130e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 19, 16); 66140e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 3, 0); 66150e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6616bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 66170e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = BitIsSet (opcode, 24); 66180e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = BitIsSet (opcode, 23); 66190e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 66200e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66210e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 66220e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 66230e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = 0; 66240e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66250e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 66260e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ((t == 15) || (m == 15)) 66270e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66280e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66290e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 66300e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (wback && ((n == 15) || (n == t))) 66310e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66320e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66330e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 66340e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66350e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice default: 66360e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66370e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 66380e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66390e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 66400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 66420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 66430e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 66460e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66470e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t offset_addr; 66480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t address; 66490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 66510e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 66520e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 66530e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (add) 66560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = Rn + offset; 66570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else 66580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = Rn - offset; 66590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // address = if index then offset_addr else R[n]; 66610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (index) 66620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = offset_addr; 66630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else 66640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = Rn; 66650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // data = MemU[address,2]; 66670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice Register base_reg; 66680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice Register offset_reg; 66690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 66700e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 66710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice EmulateInstruction::Context context; 66730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextRegisterLoad; 66740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 66750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 66760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 66770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66780e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if wback then R[n] = offset_addr; 66800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (wback) 66810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 66820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextAdjustBaseRegister; 66830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetAddress (offset_addr); 66840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 66850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 66870e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6688bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 66890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 66900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 66910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // R[t] = ZeroExtend(data, 32); 66920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextRegisterLoad; 66930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 66940e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 66950e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 66970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else // Can only apply before ARMv7 66980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 66990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // R[t] = bits(32) UNKNOWN; 67000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice WriteBits32Unknown (t); 67010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 67020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 67030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return true; 67040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice} 67050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6706a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6707a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6708a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// or pre-indexed addressing. 6709a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Ticebool 67107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6711a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice{ 6712a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#if 0 6713a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if ConditionPassed() then 6714a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6715a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6716a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = if index then offset_addr else R[n]; 6717a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 6718a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if wback then R[n] = offset_addr; 6719a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#endif 6720a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6721a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool success = false; 6722a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 67237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6724a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6725a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t t; 6726a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t n; 6727a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm32; 6728a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool index; 6729a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool add; 6730a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool wback; 6731a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6732a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6733a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice switch (encoding) 6734a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6735a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingT1: 6736bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6737bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6738a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6739a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6740a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6741a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6742a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6743a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 6744a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = true; 6745a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = true; 6746a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = false; 6747a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6748a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if t == 13 then UNPREDICTABLE; 6749a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (t == 13) 6750a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6751a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6752a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6753a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6754a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingT2: 6755bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6756bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6757bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6758bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 6759a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6760a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6761a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6762a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6763a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6764a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6765a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice imm32 = Bits32 (opcode, 7, 0); 6766a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6767bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6768a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = BitIsSet (opcode, 10); 6769a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = BitIsSet (opcode, 9); 6770a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = BitIsSet (opcode, 8); 6771a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6772a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6773bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (((t == 13) || ((t == 15) 6774bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6775bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || (wback && (n == t))) 6776a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6777a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6778a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6779a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6780a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingA1: 6781a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6782bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6783bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSBT; 6784a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6785a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6786a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6787a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6788a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 6789a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 679040b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 6791a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6792bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6793a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = BitIsSet (opcode, 24); 6794a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = BitIsSet (opcode, 23); 6795a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6796a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6797a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 6798a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if ((t == 15) || (wback && (n == t))) 6799a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6800a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6801a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6802a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6803a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6804a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice default: 6805a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6806a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6807a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6808bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice uint64_t Rn = ReadCoreReg (n, &success); 6809a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!success) 6810a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6811a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6812a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice addr_t offset_addr; 6813a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice addr_t address; 6814a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6815a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6816a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (add) 6817a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = Rn + imm32; 6818a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice else 6819a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = Rn - imm32; 6820a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6821a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // address = if index then offset_addr else R[n]; 6822a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (index) 6823a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = offset_addr; 6824a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice else 6825a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = Rn; 6826a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6827a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 6828a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice Register base_reg; 6829a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 6830a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6831a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice EmulateInstruction::Context context; 6832a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.type = eContextRegisterLoad; 6833a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 6834a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6835a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 6836a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!success) 6837a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6838a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6839a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 6840a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 6841a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6842a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6843a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if wback then R[n] = offset_addr; 6844a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (wback) 6845a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6846a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.type = eContextAdjustBaseRegister; 6847a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.SetAddress (offset_addr); 6848a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6849a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6850a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6851a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6852a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6853a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return true; 6854a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice} 68550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68565f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 68575f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// sign-extends it to form a 32-bit word, and writes tit to a register. 68585f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Ticebool 68597bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 68605f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice{ 68615f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#if 0 68625f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if ConditionPassed() then 68635f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 68645f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice base = Align(PC,4); 68655f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = if add then (base + imm32) else (base - imm32); 68665f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 68675f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#endif 68685f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68695f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice bool success = false; 68705f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 68725f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 68735f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t t; 68745f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm32; 68755f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice bool add; 68765f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68775f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 68785f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice switch (encoding) 68795f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 68805f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice case eEncodingT1: 6881bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6882bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 68835f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice t = Bits32 (opcode, 15, 12); 68845f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice imm32 = Bits32 (opcode, 11, 0); 68855f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice add = BitIsSet (opcode, 23); 68865f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68875f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // if t == 13 then UNPREDICTABLE; 68885f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (t == 13) 68895f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 68905f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68915f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice break; 68925f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68935f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice case eEncodingA1: 68945f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 6895bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 68965f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice t = Bits32 (opcode, 15, 12); 68975f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 68985f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 689940b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 69005f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice add = BitIsSet (opcode, 23); 69015f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69025f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // if t == 15 then UNPREDICTABLE; 69035f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (t == 15) 69045f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69055f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69065f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice break; 69075f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 69085f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69095f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice default: 69105f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69115f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 69125f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69135f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // base = Align(PC,4); 69148d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 69155f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!success) 69165f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69175f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint64_t base = AlignPC (pc_value); 69185f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69195f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // address = if add then (base + imm32) else (base - imm32); 69205f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice addr_t address; 69215f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (add) 69225f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = base + imm32; 69235f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice else 69245f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = base - imm32; 69255f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69265f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 69275f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice Register base_reg; 69285f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 69295f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69305f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice EmulateInstruction::Context context; 69315f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice context.type = eContextRegisterLoad; 69325f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 69335f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69345f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 69355f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!success) 69365f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69375f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69385f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 69395f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 69405f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69415f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 69425f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return true; 69435f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice} 69445f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 6945672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 6946672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 6947672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// shifted left by 0, 1, 2, or 3 bits. 6948672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Ticebool 69497bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 6950672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice{ 6951672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#if 0 6952672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ConditionPassed() then 6953672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6954672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 6955672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6956672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = if index then offset_addr else R[n]; 6957672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 6958672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if wback then R[n] = offset_addr; 6959672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#endif 6960672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6961672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool success = false; 6962672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 69637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6964672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 6965672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t t; 6966672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t n; 6967672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t m; 6968672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool index; 6969672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool add; 6970672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool wback; 6971672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice ARM_ShifterType shift_t; 6972672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t shift_n; 6973672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6974672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6975672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice switch (encoding) 6976672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 6977672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingT1: 6978672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6979672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 2, 0); 6980672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 5, 3); 6981672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 8, 6); 6982672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6983672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 6984672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = true; 6985672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = true; 6986672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = false; 6987672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6988672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 6989672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 6990672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = 0; 6991672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6992672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 6993672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6994672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingT2: 6995bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6996bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6997672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6998672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 15, 12); 6999672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 19, 16); 7000672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 3, 0); 7001672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7002672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7003672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = true; 7004672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = true; 7005672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = false; 7006672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7007672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7008672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7009672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = Bits32 (opcode, 5, 4); 7010672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7011672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 7012672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ((t == 13) || BadReg (m)) 7013672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7014672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7015672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7016672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingA1: 7017bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSBT; 7018672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7019672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 15, 12); 7020672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 19, 16); 7021672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 3, 0); 7022672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7023bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7024672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = BitIsSet (opcode, 24); 7025672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = BitIsSet (opcode, 23); 7026672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7027672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7028672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7029672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7030672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = 0; 7031672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7032672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 7033672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ((t == 15) || (m == 15)) 7034672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7035672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7036672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7037672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (wback && ((n == 15) || (n == t))) 7038672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7039672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7040672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7041672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice default: 7042672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7043672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7044672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7045672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7046672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7047672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7048672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7049672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7050672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 7051672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7052672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t offset_addr; 7053672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t address; 7054672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7055672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7056672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7057672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7058672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7059672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7060672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (add) 7061672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = Rn + offset; 7062672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice else 7063672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = Rn - offset; 7064672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7065672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // address = if index then offset_addr else R[n]; 7066672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (index) 7067672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = offset_addr; 7068672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice else 7069672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = Rn; 7070672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7071672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 7072672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice Register base_reg; 7073672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 7074672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice Register offset_reg; 7075672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 7076672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7077672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice EmulateInstruction::Context context; 7078672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.type = eContextRegisterLoad; 7079672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7080672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7081672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7082672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7083672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7084672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7085672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7086672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7087672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7088672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7089672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if wback then R[n] = offset_addr; 7090672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (wback) 7091672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 7092672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.type = eContextAdjustBaseRegister; 7093672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.SetAddress (offset_addr); 7094672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7095672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7096672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7097672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7098672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return true; 7099672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice} 7100672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 710178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 710278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 710378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// pre-indexed addressing. 710478fb5638da9c01a39443f3339ede2f02056822cfCaroline Ticebool 71057bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 710678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice{ 710778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#if 0 710878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if ConditionPassed() then 710978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 711078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 711178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = if index then offset_addr else R[n]; 711278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice data = MemU[address,2]; 711378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if wback then R[n] = offset_addr; 7114bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 711578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice R[t] = SignExtend(data, 32); 711678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else // Can only apply before ARMv7 711778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice R[t] = bits(32) UNKNOWN; 711878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#endif 711978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 712078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool success = false; 712178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 71227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 712378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 712478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t t; 712578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t n; 712678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm32; 712778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool index; 712878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool add; 712978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool wback; 713078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 713178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 713278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice switch (encoding) 713378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 713478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingT1: 7135bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7136bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 713778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 713878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 713978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 714078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice imm32 = Bits32 (opcode, 11, 0); 714178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 714278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 714378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = true; 714478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = true; 714578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = false; 714678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 714778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if t == 13 then UNPREDICTABLE; 714878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (t == 13) 714978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 715078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 715178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 715278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 715378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingT2: 7154bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7155bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7156bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7157bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 715878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 715978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 716078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 716178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 716278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 716378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 716478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice imm32 = Bits32 (opcode, 7, 0); 716578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7166bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 716778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = BitIsSet (opcode, 10); 716878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = BitIsSet (opcode, 9); 716978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = BitIsSet (opcode, 8); 717078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 717178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 717278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (BadReg (t) || (wback && (n == t))) 717378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 717478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 717578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 717678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 717778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingA1: 717878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 7179bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7180bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSHT; 718178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 718278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 718378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 718478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm4H = Bits32 (opcode, 11,8); 718578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 718640b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 718778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7188bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 718978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = BitIsSet (opcode, 24); 719078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = BitIsSet (opcode, 23); 719178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 719278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 719378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 719478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if ((t == 15) || (wback && (n == t))) 719578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 719678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 719778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 719878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 719978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 720078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice default: 720178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 720278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 720378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 720478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 720578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 720678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!success) 720778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 720878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 720978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice addr_t offset_addr; 721078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (add) 721178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = Rn + imm32; 721278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else 721378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = Rn - imm32; 721478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 721578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // address = if index then offset_addr else R[n]; 721678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice addr_t address; 721778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (index) 721878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = offset_addr; 721978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else 722078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = Rn; 722178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 722278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // data = MemU[address,2]; 722378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice Register base_reg; 722478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 722578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 722678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice EmulateInstruction::Context context; 722778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextRegisterLoad; 722878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 722978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 723078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 723178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!success) 723278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 723378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 723478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if wback then R[n] = offset_addr; 723578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (wback) 723678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 723778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextAdjustBaseRegister; 723878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetAddress (offset_addr); 723978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 724078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 724178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 724278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7243bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 724478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 724578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 724678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // R[t] = SignExtend(data, 32); 724778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 724878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextRegisterLoad; 724978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 725078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 725178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 725278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 725378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else // Can only apply before ARMv7 725478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 725578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // R[t] = bits(32) UNKNOWN; 725678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice WriteBits32Unknown (t); 725778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 725878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 725978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return true; 726078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice} 726178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7262d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7263d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// sign-extends it to from a 32-bit word, and writes it to a register. 7264d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Ticebool 72657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7266d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice{ 7267d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#if 0 7268d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if ConditionPassed() then 7269d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7270d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice base = Align(PC,4); 7271d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = if add then (base + imm32) else (base - imm32); 7272d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice data = MemU[address,2]; 7273bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 7274d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice R[t] = SignExtend(data, 32); 7275d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else // Can only apply before ARMv7 7276d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice R[t] = bits(32) UNKNOWN; 7277d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#endif 7278d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7279d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice bool success = false; 7280d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 72817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7282d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7283d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t t; 7284d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm32; 7285d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice bool add; 7286d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7287d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7288d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice switch (encoding) 7289d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7290d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice case eEncodingT1: 7291bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 7292bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7293d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice t = Bits32 (opcode, 15, 12); 7294d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice imm32 = Bits32 (opcode, 11, 0); 7295d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice add = BitIsSet (opcode, 23); 7296d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7297d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // if t == 13 then UNPREDICTABLE; 7298d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (t == 13) 7299d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7300d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7301d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice break; 7302d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7303d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice case eEncodingA1: 7304d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7305bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7306d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice t = Bits32 (opcode, 15, 12); 7307d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 7308d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 730940b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 7310d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice add = BitIsSet (opcode, 23); 7311d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7312d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // if t == 15 then UNPREDICTABLE; 7313d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (t == 15) 7314d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7315d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7316d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice break; 7317d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7318d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice default: 7319d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7320d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7321d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7322d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // base = Align(PC,4); 73238d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7324d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!success) 7325d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7326d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7327d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint64_t base = AlignPC (pc_value); 7328d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7329d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice addr_t address; 7330d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // address = if add then (base + imm32) else (base - imm32); 7331d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (add) 7332d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = base + imm32; 7333d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else 7334d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = base - imm32; 7335d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7336d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // data = MemU[address,2]; 7337d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice Register base_reg; 7338d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 7339d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7340d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice EmulateInstruction::Context context; 7341d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice context.type = eContextRegisterLoad; 7342d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice context.SetRegisterPlusOffset (base_reg, imm32); 7343d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7344d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 7345d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!success) 7346d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7347d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7348bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 7349d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 7350d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7351d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // R[t] = SignExtend(data, 32); 7352d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 7353d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7354d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7355d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7356d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else // Can only apply before ARMv7 7357d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7358d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // R[t] = bits(32) UNKNOWN; 7359d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice WriteBits32Unknown (t); 7360d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7361d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7362d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return true; 7363d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice} 7364d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7365291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7366291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7367291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// shifted left by 0, 1, 2, or 3 bits. 7368291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Ticebool 73697bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7370291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice{ 7371291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#if 0 7372291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ConditionPassed() then 7373291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7374291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 7375291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7376291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = if index then offset_addr else R[n]; 7377291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice data = MemU[address,2]; 7378291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if wback then R[n] = offset_addr; 7379bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 7380291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice R[t] = SignExtend(data, 32); 7381291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else // Can only apply before ARMv7 7382291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice R[t] = bits(32) UNKNOWN; 7383291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#endif 7384291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7385291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool success = false; 7386291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 73877bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7388291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7389291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t t; 7390291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t n; 7391291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t m; 7392291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool index; 7393291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool add; 7394291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool wback; 7395291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice ARM_ShifterType shift_t; 7396291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t shift_n; 7397291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7398291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7399291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice switch (encoding) 7400291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7401291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingT1: 7402291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7403291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7404291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 2, 0); 7405291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 5, 3); 7406291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 8, 6); 7407291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7408291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7409291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = true; 7410291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = true; 7411291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = false; 7412291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7413291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7414291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7415291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = 0; 7416291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7417291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7418291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7419291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingT2: 7420bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7421bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 7422291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7423291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 15, 12); 7424291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 19, 16); 7425291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 3, 0); 7426291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7427291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7428291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = true; 7429291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = true; 7430291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = false; 7431291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7432291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7433291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7434291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = Bits32 (opcode, 5, 4); 7435291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7436291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 7437291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ((t == 13) || BadReg (m)) 7438291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7439291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7440291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7441291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7442291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingA1: 7443bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSHT; 7444291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7445291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 15, 12); 7446291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 19, 16); 7447291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 3, 0); 7448291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7449bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7450291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = BitIsSet (opcode, 24); 7451291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = BitIsSet (opcode, 23); 7452291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7453291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7454291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7455291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7456291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = 0; 7457291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7458291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 7459291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ((t == 15) || (m == 15)) 7460291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7461291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7462291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7463291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (wback && ((n == 15) || (n == t))) 7464291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7465291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7466291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7467291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7468291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice default: 7469291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7470291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7471291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7472291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7473291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7474291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7475291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7476291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7477291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7478291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7479291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7480291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7481291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 7482291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7483291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t offset_addr; 7484291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t address; 7485291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7486291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7487291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (add) 7488291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = Rn + offset; 7489291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else 7490291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = Rn - offset; 7491291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7492291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // address = if index then offset_addr else R[n]; 7493291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (index) 7494291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = offset_addr; 7495291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else 7496291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = Rn; 7497291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7498291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // data = MemU[address,2]; 7499291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice Register base_reg; 7500291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 7501291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7502291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice Register offset_reg; 7503291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 7504291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7505291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice EmulateInstruction::Context context; 7506291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextRegisterLoad; 7507291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7508291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7509291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 7510291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7511291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7512291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7513291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if wback then R[n] = offset_addr; 7514291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (wback) 7515291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7516291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextAdjustBaseRegister; 7517291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetAddress (offset_addr); 7518291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7519291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7520291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7521291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7522bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 7523291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 7524291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7525291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // R[t] = SignExtend(data, 32); 7526291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextRegisterLoad; 7527291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7528291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7529291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 7530291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7531291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7532291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7533291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else // Can only apply before ARMv7 7534291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7535291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // R[t] = bits(32) UNKNOWN; 7536291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice WriteBits32Unknown (t); 7537291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7538291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7539291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return true; 7540291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice} 75416bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75426bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 75436bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 75446bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Ticebool 75457bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 75466bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice{ 75476bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#if 0 75486bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if ConditionPassed() then 75496bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice EncodingSpecificOperations(); 75506bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotated = ROR(R[m], rotation); 75516bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice R[d] = SignExtend(rotated<7:0>, 32); 75526bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#endif 75536bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75546bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice bool success = false; 75556bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 75576bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 75586bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t d; 75596bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t m; 75606bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t rotation; 75616bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75626bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // EncodingSpecificOperations(); 75636bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice switch (encoding) 75646bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 75656bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingT1: 75666bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 75676bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 2, 0); 75686bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 5, 3); 75696bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = 0; 75706bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75716bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 75726bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75736bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingT2: 7574bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 75756bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 11, 8); 75766bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 3, 0); 75776bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 75786bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75796bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 75806bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if (BadReg (d) || BadReg (m)) 75816bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 75826bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75836bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 75846bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75856bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingA1: 7586bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 75876bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 15, 12); 75886bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 3, 0); 75896bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 75906bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75916bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 75926bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if ((d == 15) || (m == 15)) 75936bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 75946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75956bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 75966bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75976bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice default: 75986bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 75996bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice } 76006bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 7601868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7602868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (!success) 7603868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 76046bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76056bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // rotated = ROR(R[m], rotation); 76066bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint64_t rotated = ROR (Rm, rotation); 76076bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76086bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // R[d] = SignExtend(rotated<7:0>, 32); 76098ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice int64_t data = llvm::SignExtend64<8>(rotated); 76106bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76116bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice Register source_reg; 76126bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 76136bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76146bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice EmulateInstruction::Context context; 76156bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice context.type = eContextRegisterLoad; 76166bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice context.SetRegister (source_reg); 76176bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76188ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 76196bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 76206bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice } 76216bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return true; 76226bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice} 7623291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7624868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7625868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7626868198b229fcffbda2b24518007179ef1a45ad1dCaroline Ticebool 76277bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7628868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice{ 7629868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#if 0 7630868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if ConditionPassed() then 7631868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice EncodingSpecificOperations(); 7632868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotated = ROR(R[m], rotation); 7633868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice R[d] = SignExtend(rotated<15:0>, 32); 7634868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#endif 7635868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7636868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice bool success = false; 7637868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 76387bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7639868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 7640868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t d; 7641868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t m; 7642868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t rotation; 7643868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7644868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // EncodingSpecificOperations(); 7645868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice switch (encoding) 7646868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 7647868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingT1: 7648868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7649868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 2, 0); 7650868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 5, 3); 7651868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = 0; 7652868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7653868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7654868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7655868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingT2: 7656bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7657868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 11, 8); 7658868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 3, 0); 7659868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 7660868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7661868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7662868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (BadReg (d) || BadReg (m)) 7663868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7664868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7665868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7666868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7667868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingA1: 7668bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7669868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 15, 12); 7670868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 3, 0); 7671868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 7672868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7673868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 7674868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if ((d == 15) || (m == 15)) 7675868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7676868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7677868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7678868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7679868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice default: 7680868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7681868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice } 7682868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7683868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7684868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (!success) 7685868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7686868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7687868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // rotated = ROR(R[m], rotation); 7688868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t rotated = ROR (Rm, rotation); 7689868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7690868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // R[d] = SignExtend(rotated<15:0>, 32); 7691868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice Register source_reg; 7692868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 7693868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7694868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice EmulateInstruction::Context context; 7695868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice context.type = eContextRegisterLoad; 7696868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice context.SetRegister (source_reg); 7697868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 76988ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice int64_t data = llvm::SignExtend64<16> (rotated); 76998ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7700868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7701868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice } 7702868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7703868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return true; 7704868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice} 7705868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 77068ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 77078ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 77088ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Ticebool 77097bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 77108ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice{ 77118ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#if 0 77128ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if ConditionPassed() then 77138ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice EncodingSpecificOperations(); 77148ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotated = ROR(R[m], rotation); 77158ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice R[d] = ZeroExtend(rotated<7:0>, 32); 77168ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#endif 77178ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77188ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice bool success = false; 77198ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77207bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 77218ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 77228ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t d; 77238ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t m; 77248ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t rotation; 77258ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77268ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // EncodingSpecificOperations(); 77278ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice switch (encoding) 77288ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 77298ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingT1: 77308ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 77318ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 2, 0); 77328ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 5, 3); 77338ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = 0; 77348ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77358ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 77368ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77378ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingT2: 7738bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 77398ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 11, 8); 77408ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 3, 0); 77418ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 77428ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77438ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 77448ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (BadReg (d) || BadReg (m)) 77458ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77468ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77478ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 77488ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77498ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingA1: 7750bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 77518ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 15, 12); 77528ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 3, 0); 77538ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 77548ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77558ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 77568ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if ((d == 15) || (m == 15)) 77578ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77588ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77598ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 77608ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77618ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice default: 77628ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77638ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice } 77648ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77658ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 77668ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!success) 77678ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77688ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77698ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // rotated = ROR(R[m], rotation); 77708ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint64_t rotated = ROR (Rm, rotation); 77718ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77728ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // R[d] = ZeroExtend(rotated<7:0>, 32); 77738ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice Register source_reg; 77748ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 77758ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77768ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice EmulateInstruction::Context context; 77778ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice context.type = eContextRegisterLoad; 77788ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice context.SetRegister (source_reg); 77798ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77808ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 77818ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77828ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice } 77838ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return true; 77848ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice} 77858ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 778611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 778711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 778811555f2f0f21beb0312f8ebe40849487d437f493Caroline Ticebool 77897bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 779011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice{ 779111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#if 0 779211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if ConditionPassed() then 779311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice EncodingSpecificOperations(); 779411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotated = ROR(R[m], rotation); 779511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice R[d] = ZeroExtend(rotated<15:0>, 32); 779611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#endif 779711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 779811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice bool success = false; 779911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 78007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 780111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 780211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t d; 780311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t m; 780411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t rotation; 780511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 780611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice switch (encoding) 780711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 780811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingT1: 780911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 781011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 2, 0); 781111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 5, 3); 781211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = 0; 781311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 781411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 781511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 781611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingT2: 7817bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 781811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 11, 8); 781911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 3, 0); 782011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 782111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 782211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 782311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (BadReg (d) || BadReg (m)) 782411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 782511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 782611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 782711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 782811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingA1: 7829bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 783011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 15, 12); 783111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 3, 0); 783211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 783311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 783411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 783511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if ((d == 15) || (m == 15)) 783611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 783711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 783811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 783911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 784011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice default: 784111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 784211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice } 784311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 784411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 784511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (!success) 784611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 784711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 784811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // rotated = ROR(R[m], rotation); 784911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint64_t rotated = ROR (Rm, rotation); 785011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 785111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // R[d] = ZeroExtend(rotated<15:0>, 32); 785211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice Register source_reg; 785311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 785411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 785511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice EmulateInstruction::Context context; 785611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice context.type = eContextRegisterLoad; 785711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice context.SetRegister (source_reg); 785811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 785911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 786011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 786111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice } 786211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return true; 786311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice} 7864b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7865b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 7866b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// word respectively. 7867b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 78687bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 7869b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 7870b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#if 0 7871b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if ConditionPassed() then 7872b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice EncodingSpecificOperations(); 7873b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 7874b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice UNPREDICTABLE; 7875b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 7876b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = if increment then R[n] else R[n]-8; 7877b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if wordhigher then address = address+4; 7878bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 7879b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice BranchWritePC(MemA[address,4]); 7880b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if wback then R[n] = if increment then R[n]+8 else R[n]-8; 7881b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#endif 7882b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7883b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool success = false; 7884b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 78857bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7886b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7887b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint32_t n; 7888b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool wback; 7889b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool increment; 7890b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool wordhigher; 7891b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7892b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // EncodingSpecificOperations(); 7893b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice switch (encoding) 7894b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7895b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingT1: 7896bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 7897b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 7898b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 7899b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = false; 7900b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = false; 7901b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7902b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 7903b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 7904b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7905b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7906b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 7907b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (InITBlock() && !LastInITBlock()) 7908b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7909b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7910b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 7911b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7912b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingT2: 7913bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 7914b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 7915b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 7916b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = true; 7917b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = false; 7918b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7919b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 7920b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 7921b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7922b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7923b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 7924b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (InITBlock() && !LastInITBlock()) 7925b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7926b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7927b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 7928b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7929b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingA1: 7930b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // n = UInt(Rn); 7931b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 7932b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7933bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 7934b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 7935b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = BitIsSet (opcode, 23); 7936b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 7937b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7938b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 7939b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 7940b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7941b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7942b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 7943b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7944b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice default: 7945b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7946b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 7947b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7948b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 7949b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!CurrentModeIsPrivileged ()) 7950b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // UNPREDICTABLE; 7951b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7952b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 7953b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7954b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7955b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 7956b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7957b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7958b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice addr_t address; 7959b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // address = if increment then R[n] else R[n]-8; 7960b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (increment) 7961b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = Rn; 7962b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 7963b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = Rn - 8; 7964b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7965b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if wordhigher then address = address+4; 7966b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (wordhigher) 7967b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = address + 4; 7968b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7969bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 7970b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice Register base_reg; 7971b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 7972b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7973b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice EmulateInstruction::Context context; 7974b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.type = eContextReturnFromException; 7975b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 7976b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7977b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t data = MemARead (context, address + 4, 4, 0, &success); 7978b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 7979b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7980b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7981b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice CPSRWriteByInstr (data, 15, true); 7982b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7983b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // BranchWritePC(MemA[address,4]); 7984b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t data2 = MemARead (context, address, 4, 0, &success); 7985b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 7986b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7987b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7988b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice BranchWritePC (context, data2); 7989b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7990b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 7991b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (wback) 7992b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7993b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.type = eContextAdjustBaseRegister; 7994b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (increment) 7995b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7996b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetOffset (8); 7997b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 7998b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7999b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8000b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 8001b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8002b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetOffset (-8); 8003b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8004b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8005b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8006b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } // if wback 8007b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8008b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } // if ConditionPassed() 8009b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 8010b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 801111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 80122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 80132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags based on 80142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 80152115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 80167bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 80172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 80182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 80192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 80202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 80212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 80222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 80232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 80242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 80252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 80262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 80272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 80282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 80292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 80302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 80312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 80322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 80332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 80352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80367bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 80372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 80382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn; 80392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 80402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 80412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 80422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 80432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 80442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 80452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 80462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 80472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 80482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 80492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 80502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 80517bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTEQImm (opcode, eEncodingT1); 80522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 80532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 80552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 80562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 80572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 80582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 80592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 80602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 80612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 80622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 80632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 80652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 80662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 80682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 80702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 80712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 80722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 80752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 80772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 80782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 80792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 80812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 80832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 80842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 80852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 80872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value, and writes the result to the destination register. 80882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// It can optionally update the condition flags based on the result. 80892115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 80907bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 80912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 80922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 80932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 80942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 80952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 80962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 80972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 80982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 80992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 81002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 81012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 81022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 81032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 81042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 81052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 81062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 81072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 81082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 81102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81117bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 81122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 81132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn, Rm; 81142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 81152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 81162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 81172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 81182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 81192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 81202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 81212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 81222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 5, 3); 81232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = !InITBlock(); 81242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_t = SRType_LSL; 81252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = 0; 8126ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 81272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT2: 81282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 81292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 81302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 81312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 81323dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 81333dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (register); 81342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 81357bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTEQReg (opcode, eEncodingT1); 81362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 81372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 81392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 81402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 81412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 81422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 81432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 81443dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 81452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 81462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 81472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 81482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 81502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 81512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 81532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 81552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 81562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 81572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 81602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 81612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 81622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 81652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 81662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 81682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 81692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 81702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 81722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 81742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 81752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 81762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 81787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// writes the result to the destination register. It can optionally update the condition flags based 81797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 81807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 81817bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 81827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 81837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 81847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 81857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 81867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 81877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR imm32; 81887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 81897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 81907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 81917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 81927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 81937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 81947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 81957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 81967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 81977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 81987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 81997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 82007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82017bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 82027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn; 82047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 82057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 82067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 82077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 82087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 82107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 82117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 82127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 82137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8214bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE MOV (immediate); 82157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 82167bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdImm (opcode, eEncodingT2); 82177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13) 82187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 82207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 82217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 82227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 82237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 82247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 82257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 82267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 82277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 82297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 82307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 82327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 82347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 82357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 82367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = val1 | imm32; 82397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 82417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 82427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 82437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 82457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 82477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 82487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 82497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 82517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// value, and writes the result to the destination register. It can optionally update the condition flags based 82527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 82537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 82547bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 82557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 82567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 82577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 82587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 82597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 82607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 82617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR shifted; 82627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 82637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 82647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 82657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 82667c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 82677c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 82687c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 82697c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 82707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 82717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 82727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 82747c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82757bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 82767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn, Rm; 82787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ARM_ShifterType shift_t; 82797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 82807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 82817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; 82827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 82837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 82857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 82867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 5, 3); 82877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = !InITBlock(); 82887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_t = SRType_LSL; 82897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_n = 0; 8290ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 82917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT2: 82927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 82937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 82947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 82957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 82963dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 82973dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen // if Rn == '1111' then SEE MOV (register); 82987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 82997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdRm (opcode, eEncodingT3); 83007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 83017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 83037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 83047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 83057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 83067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 83077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 83083dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 83097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 83107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 83117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 83137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 83147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 83167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 83187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 83197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 83207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the second operand. 83237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 83247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 83257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 83282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 | shifted; 83297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 83317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 83327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 83337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 83357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 83377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 83387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 83397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 8340ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8341ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// the destination register. It can optionally update the condition flags based on the result. 8342ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool 83437bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8344ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{ 8345ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0 8346ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // ARM pseudo code... 8347ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if ConditionPassed() then 8348ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EncodingSpecificOperations(); 8349ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8350ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if d == 15 then // Can only occur for ARM encoding 8351ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ALUWritePC(result); // setflags is always FALSE here 8352ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen else 8353ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen R[d] = result; 8354ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if setflags then 8355ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.N = result<31>; 8356ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.Z = IsZeroBit(result); 8357ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.C = carry; 8358ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.V = overflow; 8359ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif 8360ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8361ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool success = false; 8362ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8363ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rd; // the destination register 8364ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rn; // the first operand 8365ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool setflags; 8366ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8367ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen switch (encoding) { 8368ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT1: 8369ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 2, 0); 8370ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 5, 3); 8371ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = !InITBlock(); 8372ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = 0; 8373ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8374ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT2: 8375ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 11, 8); 8376ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8377ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8378ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8379ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 8380ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8381ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8382ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingA1: 8383ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 15, 12); 8384ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8385ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8386ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8387ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8388ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 8389ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (Rd == 15 && setflags) 8390ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8391ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8392ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen default: 8393ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8394ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen } 8395ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from the operand register Rn. 8396ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 8397ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8398ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8399ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8400ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8401ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8402ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EmulateInstruction::Context context; 8403ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.type = EmulateInstruction::eContextImmediate; 8404ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.SetNoArgs (); 8405ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8406ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8407ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8408ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8409ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return true; 8410ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen} 8411ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8412ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8413ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// result to the destination register. It can optionally update the condition flags based on the result. 8414ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool 84157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8416ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{ 8417ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0 8418ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // ARM pseudo code... 8419ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if ConditionPassed() then 8420ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EncodingSpecificOperations(); 8421ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8422ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8423ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if d == 15 then // Can only occur for ARM encoding 8424ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ALUWritePC(result); // setflags is always FALSE here 8425ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen else 8426ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen R[d] = result; 8427ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if setflags then 8428ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.N = result<31>; 8429ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.Z = IsZeroBit(result); 8430ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.C = carry; 8431ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.V = overflow; 8432ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif 8433ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8434ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool success = false; 8435ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8436ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rd; // the destination register 8437ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rn; // the first operand 8438ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rm; // the second operand 8439ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool setflags; 8440ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ARM_ShifterType shift_t; 8441ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 8442ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen switch (encoding) { 8443ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT1: 8444ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 11, 8); 8445ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8446ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rm = Bits32(opcode, 3, 0); 8447ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8448ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 8449ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8450ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8451ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8452ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8453ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingA1: 8454ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 15, 12); 8455ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8456ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rm = Bits32(opcode, 3, 0); 8457ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8458ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 8459ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8460ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 8461ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (Rd == 15 && setflags) 8462ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8463ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8464ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen default: 8465ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8466ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen } 8467ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from register Rn. 8468ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 8469ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8470ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8471ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8472ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from register Rm. 8473ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 8474ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8475ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8476ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8477ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 8478ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8479ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8480ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EmulateInstruction::Context context; 8481ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.type = EmulateInstruction::eContextImmediate; 8482ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.SetNoArgs(); 8483ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8484ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8485ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8486ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return true; 8487ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen} 8488ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 848990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 849090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// an immediate value, and writes the result to the destination register. It can optionally update the condition 849190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// flags based on the result. 849290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool 84937bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 849490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{ 849590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0 849690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // ARM pseudo code... 849790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if ConditionPassed() then 849890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EncodingSpecificOperations(); 849990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 850090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if d == 15 then 850190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ALUWritePC(result); // setflags is always FALSE here 850290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen else 850390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen R[d] = result; 850490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if setflags then 850590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.N = result<31>; 850690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.Z = IsZeroBit(result); 850790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.C = carry; 850890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.V = overflow; 850990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif 851090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 851190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool success = false; 851290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 851390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rd; // the destination register 851490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rn; // the first operand 851590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool setflags; 851690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 851790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen switch (encoding) { 851890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen case eEncodingA1: 851990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rd = Bits32(opcode, 15, 12); 852090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rn = Bits32(opcode, 19, 16); 852190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen setflags = BitIsSet(opcode, 20); 852290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 852390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 852490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 852590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (Rd == 15 && setflags) 852690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 852790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen break; 852890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen default: 852990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 853090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen } 853190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from the operand register Rn. 853290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 853390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 853490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 853590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 853690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 853790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 853890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EmulateInstruction::Context context; 853990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.type = EmulateInstruction::eContextImmediate; 854090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.SetNoArgs (); 854190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 854290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 854390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 854490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 854590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return true; 854690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen} 854790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 854890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 854990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 855090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// condition flags based on the result. 855190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool 85527bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 855390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{ 855490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0 855590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // ARM pseudo code... 855690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if ConditionPassed() then 855790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EncodingSpecificOperations(); 855890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 855990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 856090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if d == 15 then 856190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ALUWritePC(result); // setflags is always FALSE here 856290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen else 856390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen R[d] = result; 856490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if setflags then 856590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.N = result<31>; 856690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.Z = IsZeroBit(result); 856790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.C = carry; 856890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.V = overflow; 856990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif 857090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 857190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool success = false; 857290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 857390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rd; // the destination register 857490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rn; // the first operand 857590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rm; // the second operand 857690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool setflags; 857790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ARM_ShifterType shift_t; 857890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 857990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen switch (encoding) { 858090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen case eEncodingA1: 858190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rd = Bits32(opcode, 15, 12); 858290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rn = Bits32(opcode, 19, 16); 858390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rm = Bits32(opcode, 3, 0); 858490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen setflags = BitIsSet(opcode, 20); 858590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 858690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 858790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 858890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (Rd == 15 && setflags) 858990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 859090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen break; 859190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen default: 859290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 859390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen } 859490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from register Rn. 859590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 859690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 859790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 859890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 859990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from register Rm. 860090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 860190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 860290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 860390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 860490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 860590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 860690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 860790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EmulateInstruction::Context context; 860890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.type = EmulateInstruction::eContextImmediate; 860990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.SetNoArgs(); 861090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 861190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 861290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 861390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return true; 861490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen} 861590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 86169b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (immediate) subtracts an immediate value and the value of 86179b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register. 86189b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result. 86199b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool 86207bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 86219b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{ 86229b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0 86239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // ARM pseudo code... 86249b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if ConditionPassed() then 86259b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EncodingSpecificOperations(); 862615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 86279b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if d == 15 then // Can only occur for ARM encoding 86289b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 86299b381775c532270fd07a90aa1a98750546a768b7Johnny Chen else 86309b381775c532270fd07a90aa1a98750546a768b7Johnny Chen R[d] = result; 86319b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if setflags then 86329b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.N = result<31>; 86339b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.Z = IsZeroBit(result); 86349b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.C = carry; 86359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.V = overflow; 86369b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif 86379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86389b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool success = false; 86399b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86409b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rd; // the destination register 86419b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rn; // the first operand 86429b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool setflags; 86439b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 86449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen switch (encoding) { 86459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT1: 86469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 11, 8); 86479b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 86489b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 86499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 86509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 86519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 86539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingA1: 86549b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 15, 12); 86559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 86569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 86579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 86589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 86599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 86609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (Rd == 15 && setflags) 86619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 86639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen default: 86649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86659b381775c532270fd07a90aa1a98750546a768b7Johnny Chen } 86669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from the operand register Rn. 86679b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 86689b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 86699b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86709b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86719b381775c532270fd07a90aa1a98750546a768b7Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 86729b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86739b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EmulateInstruction::Context context; 86749b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 86759b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.SetNoArgs (); 86769b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86779b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 86789b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86799b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86809b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return true; 86819b381775c532270fd07a90aa1a98750546a768b7Johnny Chen} 86829b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86839b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 86849b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register. 86859b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result. 86869b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool 86877bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 86889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{ 86899b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0 86909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // ARM pseudo code... 86919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if ConditionPassed() then 86929b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EncodingSpecificOperations(); 86939b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 86949b381775c532270fd07a90aa1a98750546a768b7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 86959b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if d == 15 then // Can only occur for ARM encoding 86969b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 86979b381775c532270fd07a90aa1a98750546a768b7Johnny Chen else 86989b381775c532270fd07a90aa1a98750546a768b7Johnny Chen R[d] = result; 86999b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if setflags then 87009b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.N = result<31>; 87019b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.Z = IsZeroBit(result); 87029b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.C = carry; 87039b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.V = overflow; 87049b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif 87059b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87069b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool success = false; 87079b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87089b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rd; // the destination register 87099b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rn; // the first operand 87109b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rm; // the second operand 87119b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool setflags; 87129b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ARM_ShifterType shift_t; 87139b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 87149b381775c532270fd07a90aa1a98750546a768b7Johnny Chen switch (encoding) { 87159b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT1: 87169b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 87179b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 5, 3); 87189b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = !InITBlock(); 87199b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_t = SRType_LSL; 87209b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = 0; 87219b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 87229b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT2: 87239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 11, 8); 87249b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 87259b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 3, 0); 87269b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 87279b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 87289b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 87299b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87309b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 87319b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingA1: 87329b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 15, 12); 87339b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 87349b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 3, 0); 87359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 87369b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 87379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 87389b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 87399b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (Rd == 15 && setflags) 87409b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87419b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 87429b381775c532270fd07a90aa1a98750546a768b7Johnny Chen default: 87439b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen } 87459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from register Rn. 87469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 87479b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 87489b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from register Rm. 87519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 87529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 87539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87549b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 87569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 87579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EmulateInstruction::Context context; 87599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 87609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.SetNoArgs(); 87619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 87629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return true; 87659b381775c532270fd07a90aa1a98750546a768b7Johnny Chen} 87669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 876715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result 876815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register. It can optionally update the condition flags based on the result. 876915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool 87707bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 877115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{ 877215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0 877315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // ARM pseudo code... 877415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if ConditionPassed() then 877515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EncodingSpecificOperations(); 877615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 877715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen R[d] = result; 877815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if setflags then 877915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.N = result<31>; 878015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.Z = IsZeroBit(result); 878115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.C = carry; 878215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.V = overflow; 878315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif 878415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 878515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool success = false; 878615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 878715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rd; // the destination register 878815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rn; // the first operand 878915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool setflags; 879015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 879115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen switch (encoding) { 879215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT1: 879315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 2, 0); 879415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 5, 3); 879515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = !InITBlock(); 879615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 879715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 879815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT2: 879915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Rn = Bits32(opcode, 10, 8); 880015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = !InITBlock(); 880115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 880215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 880315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT3: 880415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 11, 8); 880515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 880615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 880715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 880815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 880915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE CMP (immediate); 881015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 88117bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateCMPImm (opcode, eEncodingT2); 881215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 8813bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE SUB (SP minus immediate); 881415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 88157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingT2); 881615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 881715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 881815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 881915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 882015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 882115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT4: 882215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 11, 8); 882315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 882415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 882515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 882615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 882715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rn == '1111' then SEE ADR; 882815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 15) 88297bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateADR (opcode, eEncodingT2); 883015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 883115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rn == '1101' then SEE SUB (SP minus immediate); 883215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 88337bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingT3); 883415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 883515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (BadReg(Rd)) 883615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 883715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 883815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen default: 883915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 884015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen } 884115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // Read the register value from the operand register Rn. 884215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 884315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!success) 884415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 884515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 884615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 884715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 884815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EmulateInstruction::Context context; 884915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.type = EmulateInstruction::eContextImmediate; 885015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.SetNoArgs (); 885115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 885215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 885315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 885415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 885515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return true; 885615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen} 885715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 885815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result 885915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register. It can optionally update the condition flags based on the result. 886015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool 88617bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 886215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{ 886315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0 886415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // ARM pseudo code... 886515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if ConditionPassed() then 886615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EncodingSpecificOperations(); 886715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 886815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if d == 15 then 886915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen ALUWritePC(result); // setflags is always FALSE here 887015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen else 887115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen R[d] = result; 887215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if setflags then 887315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.N = result<31>; 887415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.Z = IsZeroBit(result); 887515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.C = carry; 887615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.V = overflow; 887715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif 887815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 887915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool success = false; 888015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 888115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rd; // the destination register 888215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rn; // the first operand 888315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool setflags; 888415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 888515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen switch (encoding) { 888615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingA1: 888715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 15, 12); 888815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 888915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 889015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 889115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 8892bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' && S == '0' then SEE ADR; 889315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 15 && !setflags) 88947bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateADR (opcode, eEncodingA2); 889515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 8896bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE SUB (SP minus immediate); 889715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 88987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingA1); 889915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 890015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 890115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 890215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 890315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 890415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 890515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen default: 890615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 890715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen } 890815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // Read the register value from the operand register Rn. 890915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 891015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!success) 891115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 891215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 891315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 891415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 891515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EmulateInstruction::Context context; 891615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.type = EmulateInstruction::eContextImmediate; 891715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.SetNoArgs (); 891815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 891915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 892015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 892115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 892215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return true; 892315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen} 892415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 89252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 89262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// immediate value. It updates the condition flags based on the result, and discards the result. 89272115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 89287bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 89292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 89302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 89312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 89322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 89332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 89342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 89352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 89362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 89372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 89382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 89392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 89402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 89422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89437bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 89442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 89452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn; 89462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 89472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 89482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 89492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 89502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 89512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 89527bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 89532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn)) 89542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 89562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 89572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 89587bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 89592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 89602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 89612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 89632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 89652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 89662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 89672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 89702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 89722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 89732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 89742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 89762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 89782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 89792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 89802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 89822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value. It updates the condition flags based on the result, and discards 89832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 89842115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 89857bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 89862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 89872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 89882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 89892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 89902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 89912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 89922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 89932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 89942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 89952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 89962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 89972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 89982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 90002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90017bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 90022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 90032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn, Rm; 90042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 90052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 90062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 90072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 90082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 90092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 90102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 90112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 90123dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 90132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn) || BadReg(Rm)) 90142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 90162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 90172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 90182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 90193dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 90202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 90212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 90222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 90242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 90262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 90272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 90282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 90312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 90322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 90332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 90362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 90372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 90392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 90402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 90412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 90432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 90452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 90462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 90472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 9048de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9049de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 9050de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 90517bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9052de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 9053de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 9054de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 9055de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 9056de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 9057de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND imm32; 9058de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 9059de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 9060de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 9061de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 9062de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 9063de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9064de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 9065de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 90667bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9067de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9068de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn; 9069de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9070de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9071de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 9072de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9073de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 9074de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9075de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9076de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn)) 9077de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9078de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9079de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 9080de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9081de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9082de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9083de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 9084de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9085de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9086de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9087de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 9088de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 9089de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9090de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9091de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9092de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & imm32; 9093de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9094de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 9095de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 9096de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 9097de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9098de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 9099de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9100de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9101de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 9102de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 9103de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9104de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9105de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 9106de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 91077bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9108de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 9109de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 9110de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 9111de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 9112de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 9113de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9114de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND shifted; 9115de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 9116de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 9117de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 9118de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 9119de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 9120de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9121de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 9122de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 91237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9124de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9125de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn, Rm; 9126de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen ARM_ShifterType shift_t; 9127de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 9128de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; 9129de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 9130de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9131de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 9132de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 2, 0); 9133de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 5, 3); 9134de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_t = SRType_LSL; 9135de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_n = 0; 9136ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 9137de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT2: 9138de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9139de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 91403dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 9141de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn) || BadReg(Rm)) 9142de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9143de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9144de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 9145de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9146de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 91473dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 9148de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9149de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 9150de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9151de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9152de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9153de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 9154de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 9155de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9156de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9157de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9158de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the second operand. 9159de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 9160de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9161de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9162de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9163de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 9164de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & shifted; 9165de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9166de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 9167de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 9168de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 9169de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9170de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 9171de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9172de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9173de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 9174de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 9175d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9176d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.216 SUB (SP minus register) 9177d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9178d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9179d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9180d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9181d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ConditionPassed() then 9182d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice EncodingSpecificOperations(); 9183d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9184d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’); 9185d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if d == 15 then // Can only occur for ARM encoding 9186d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice ALUWritePC(result); // setflags is always FALSE here 9187d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice else 9188d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice R[d] = result; 9189d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if setflags then 9190d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.N = result<31>; 9191d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.Z = IsZeroBit(result); 9192d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.C = carry; 9193d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.V = overflow; 9194d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9195d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9196d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice bool success = false; 9197d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9198d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9199d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9200d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t d; 9201d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t m; 9202d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice bool setflags; 9203d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice ARM_ShifterType shift_t; 9204d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t shift_n; 9205d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9206d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9207d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9208d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice case eEncodingT1: 9209d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); 9210d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice d = Bits32 (opcode, 11, 8); 9211d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice m = Bits32 (opcode, 3, 0); 9212d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice setflags = BitIsSet (opcode, 20); 9213d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9214d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9215d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shift_n = DecodeImmShiftThumb (opcode, shift_t); 9216d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9217d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9218d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9219d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9220d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9221d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if d == 15 || BadReg(m) then UNPREDICTABLE; 9222d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ((d == 15) || BadReg (m)) 9223d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9224d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice break; 9225d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9226d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice case eEncodingA1: 9227d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 9228d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); 9229d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice d = Bits32 (opcode, 15, 12); 9230d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice m = Bits32 (opcode, 3, 0); 9231d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice setflags = BitIsSet (opcode, 20); 9232d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9233d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9234d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shift_n = DecodeImmShiftARM (opcode, shift_t); 9235d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice break; 9236d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9237d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice default: 9238d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9239d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9240d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9241d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9242d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 9243d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!success) 9244d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9245d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9246d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); 9247d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9248d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’); 9249d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9250d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!success) 9251d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9252d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9253d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9254d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9255d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice EmulateInstruction::Context context; 9256d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice context.type = eContextSubtraction; 9257d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice Register sp_reg; 9258d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 9259d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice Register dwarf_reg; 9260d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 9261d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9262d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9263ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9264d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9265d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9266d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9267d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9268d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9269d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9270d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.7 ADD (register-shifted register) 9271d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9272c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline TiceEmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9273d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9274d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9275c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if ConditionPassed() then 9276c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice EncodingSpecificOperations(); 9277c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice shift_n = UInt(R[s]<7:0>); 9278c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9279c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’); 9280c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice R[d] = result; 9281c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if setflags then 9282c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.N = result<31>; 9283c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.Z = IsZeroBit(result); 9284c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.C = carry; 9285c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice APSR.V = overflow; 9286d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9287d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9288c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice bool success = false; 9289d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9290d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9291d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9292c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t d; 9293c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t n; 9294c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t m; 9295c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t s; 9296c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice bool setflags; 9297c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice ARM_ShifterType shift_t; 9298c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9299d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9300d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9301c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice case eEncodingA1: 9302c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9303c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice d = Bits32 (opcode, 15, 12); 9304c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice n = Bits32 (opcode, 19, 16); 9305c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice m = Bits32 (opcode, 3, 0); 9306c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice s = Bits32 (opcode, 11, 8); 9307c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9308c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // setflags = (S == ‘1’); shift_t = DecodeRegShift(type); 9309c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice setflags = BitIsSet (opcode, 20); 9310c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9311c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9312c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9313c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9314c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9315c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice break; 9316c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9317c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice default: 9318c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9319d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9320c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9321c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // shift_n = UInt(R[s]<7:0>); 9322c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t Rs = ReadCoreReg (s, &success); 9323c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!success) 9324c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9325c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9326c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t shift_n = Bits32 (Rs, 7, 0); 9327c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9328c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9329c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t Rm = ReadCoreReg (m, &success); 9330c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!success) 9331c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9332c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9333c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); 9334c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9335c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’); 9336c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 9337c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!success) 9338c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9339c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9340c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9341c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9342c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // R[d] = result; 9343c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice EmulateInstruction::Context context; 9344c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice context.type = eContextAddition; 9345c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice Register reg_n; 93461697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 +n); 9347c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice Register reg_m; 93481697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 9349c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9350c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice context.SetRegisterRegisterOperands (reg_n, reg_m); 9351c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9352c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9353c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return false; 9354c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice 9355c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // if setflags then 9356c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.N = result<31>; 9357c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.Z = IsZeroBit(result); 9358c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.C = carry; 9359c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // APSR.V = overflow; 9360c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice if (setflags) 9361c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice return WriteFlags (context, res.result, res.carry_out, res.overflow); 9362d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9363d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9364d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9365d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9366d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.213 SUB (register) 9367d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9368d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9369d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9370d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 93714cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if ConditionPassed() then 93724cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice EncodingSpecificOperations(); 93734cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 93744cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’); 93754cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if d == 15 then // Can only occur for ARM encoding 93764cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice ALUWritePC(result); // setflags is always FALSE here 93774cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice else 93784cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice R[d] = result; 93794cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if setflags then 93804cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.N = result<31>; 93814cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.Z = IsZeroBit(result); 93824cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.C = carry; 93834cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice APSR.V = overflow; 9384d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9385d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 93864cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice bool success = false; 9387d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9388d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9389d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 93904cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t d; 93914cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t n; 93924cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t m; 93934cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice bool setflags; 93944cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice ARM_ShifterType shift_t; 93954cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t shift_n; 93964cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9397d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9398d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 93994cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice case eEncodingT1: 94004cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 94014cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice d = Bits32 (opcode, 2, 0); 94024cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice n = Bits32 (opcode, 5, 3); 94034cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice m = Bits32 (opcode, 8, 6); 94044cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice setflags = !InITBlock(); 94054cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94064cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 94074cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_t = SRType_LSL; 94084cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_n = 0; 94094cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94104cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice break; 94114cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94124cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice case eEncodingT2: 94134cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if Rd == ‘1111’ && S == ‘1’ then SEE CMP (register); 94144cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if Rn == ‘1101’ then SEE SUB (SP minus register); 94154cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’); 94164cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice d = Bits32 (opcode, 11, 8); 94174cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice n = Bits32 (opcode, 19, 16); 94184cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice m = Bits32 (opcode, 3, 0); 94194cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice setflags = BitIsSet (opcode, 20); 94204cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94214cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 94224cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_n = DecodeImmShiftThumb (opcode, shift_t); 94234cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94244cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 94254cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 94264cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 94274cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94284cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice break; 94294cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94304cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice case eEncodingA1: 94314cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 94324cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if Rn == ‘1101’ then SEE SUB (SP minus register); 94334cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’); 94344cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice d = Bits32 (opcode, 15, 12); 94354cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice n = Bits32 (opcode, 19, 16); 94364cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice m = Bits32 (opcode, 3, 0); 94374cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice setflags = BitIsSet (opcode, 20); 94384cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94394cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 94404cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice shift_n = DecodeImmShiftARM (opcode, shift_t); 94414cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94424cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice break; 94434cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94444cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice default: 94454cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 9446d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 94474cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94484cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 94494cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 94504cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if (!success) 94514cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 94524cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94534cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); 94544cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94554cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’); 94564cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 94574cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice if (!success) 94584cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 94594cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94604cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 94614cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94624cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if d == 15 then // Can only occur for ARM encoding 94634cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // ALUWritePC(result); // setflags is always FALSE here 94644cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // else 94654cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // R[d] = result; 94664cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // if setflags then 94674cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.N = result<31>; 94684cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.Z = IsZeroBit(result); 94694cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.C = carry; 94704cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // APSR.V = overflow; 94714cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 94724cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice EmulateInstruction::Context context; 94734cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice context.type = eContextSubtraction; 94744cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice Register reg_n; 94751697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 94764cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice Register reg_m; 94771697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 94784cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice context.SetRegisterRegisterOperands (reg_n, reg_m); 94794cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9480ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 94814cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice return false; 9482d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9483d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9484d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 94854cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice 9486d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.202 STREX 94875168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 94885168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice// word from a register to memory if the executing processor has exclusive access to the memory addressed. 9489d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9490d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9491d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9492d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 94935168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ConditionPassed() then 94945168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 94955168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice address = R[n] + imm32; 94965168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ExclusiveMonitorsPass(address,4) then 94975168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice MemA[address,4] = R[t]; 94985168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice R[d] = 0; 94995168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice else 95005168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice R[d] = 1; 9501d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9502d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 95035168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice bool success = false; 9504d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9505d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9506d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 95075168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t d; 95085168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t t; 95095168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t n; 95105168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t imm32; 95115168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 95125168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 9513d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9514d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 95155168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice case eEncodingT1: 95165168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); 95175168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice d = Bits32 (opcode, 11, 8); 95185168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice t = Bits32 (opcode, 15, 12); 95195168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice n = Bits32 (opcode, 19, 16); 95205168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 95215168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95225168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 95235168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (BadReg (d) || BadReg (t) || (n == 15)) 95245168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95255168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95265168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if d == n || d == t then UNPREDICTABLE; 95275168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ((d == n) || (d == t)) 95285168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95295168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95305168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice break; 95315168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95325168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice case eEncodingA1: 95335168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 95345168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice d = Bits32 (opcode, 15, 12); 95355168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice t = Bits32 (opcode, 3, 0); 95365168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice n = Bits32 (opcode, 19, 16); 95375168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice imm32 = 0; 95385168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95395168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 95405168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ((d == 15) || (t == 15) || (n == 15)) 95415168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95425168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95435168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if d == n || d == t then UNPREDICTABLE; 95445168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if ((d == n) || (d == t)) 95455168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95465168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95475168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice break; 95485168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95495168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice default: 95505168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95515168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice } 95525168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95535168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // address = R[n] + imm32; 95545168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 95555168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!success) 95565168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95575168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95585168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice addr_t address = Rn + imm32; 95595168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95605168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice Register base_reg; 95615168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 95625168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice Register data_reg; 95635168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 95645168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice EmulateInstruction::Context context; 95655168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice context.type = eContextRegisterStore; 95665168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 95675168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95685168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if ExclusiveMonitorsPass(address,4) then 95695168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 95705168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // always return true. 95715168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (true) 95725168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice { 95735168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // MemA[address,4] = R[t]; 95745168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 95755168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!success) 95765168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95775168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95785168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!MemAWrite (context, address, Rt, addr_byte_size)) 95795168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95805168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice 95815168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // R[d] = 0; 95825168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 95835168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 95845168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice } 95855168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice else 95865168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice { 95875168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice // R[d] = 1; 95885168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 95895168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice return false; 9590d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9591d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9592d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9593d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9594d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9595d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.197 STRB (immediate, ARM) 9596d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9597d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9598d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9599d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9600ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if ConditionPassed() then 9601ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice EncodingSpecificOperations(); 9602ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9603ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice address = if index then offset_addr else R[n]; 9604ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice MemU[address,1] = R[t]<7:0>; 9605ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if wback then R[n] = offset_addr; 9606d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9607d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9608ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool success = false; 9609d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9610d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9611d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9612ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t t; 9613ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t n; 9614ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t imm32; 9615ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool index; 9616ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool add; 9617ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice bool wback; 9618ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9619d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9620d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9621ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice case eEncodingA1: 9622ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if P == ‘0’ && W == ‘1’ then SEE STRBT; 9623ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9624ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice t = Bits32 (opcode, 15, 12); 9625ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice n = Bits32 (opcode, 19, 16); 9626ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice imm32 = Bits32 (opcode, 11, 0); 9627ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9628ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); 9629ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice index = BitIsSet (opcode, 24); 9630ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice add = BitIsSet (opcode, 23); 9631ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9632ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9633ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if t == 15 then UNPREDICTABLE; 9634ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (t == 15) 9635ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9636ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9637ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9638ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (wback && ((n == 15) || (n == t))) 9639ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9640ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9641ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice break; 9642ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9643ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice default: 9644ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9645ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice } 9646ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9647ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9648ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t Rn = ReadCoreReg (n, &success); 9649ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!success) 9650ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9651ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9652ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice addr_t offset_addr; 9653ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (add) 9654ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice offset_addr = Rn + imm32; 9655ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice else 9656ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice offset_addr = Rn - imm32; 9657ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9658ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // address = if index then offset_addr else R[n]; 9659ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice addr_t address; 9660ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (index) 9661ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice address = offset_addr; 9662ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice else 9663ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice address = Rn; 9664ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9665ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // MemU[address,1] = R[t]<7:0>; 9666ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice uint32_t Rt = ReadCoreReg (t, &success); 9667ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!success) 9668ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9669ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9670ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice Register base_reg; 96711697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 9672ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice Register data_reg; 96731697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 9674ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice EmulateInstruction::Context context; 9675ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice context.type = eContextRegisterStore; 9676ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9677ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9678ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9679ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9680ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice 9681ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice // if wback then R[n] = offset_addr; 9682ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (wback) 9683ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice { 9684ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9685ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice return false; 9686d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9687d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9688d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9689d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9690d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9691d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.194 STR (immediate, ARM) 9692d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9693d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9694d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9695d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9696d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if ConditionPassed() then 9697d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice EncodingSpecificOperations(); 9698d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9699d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice address = if index then offset_addr else R[n]; 9700d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9701d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if wback then R[n] = offset_addr; 9702d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9703d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9704d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool success = false; 9705d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9706d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9707d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9708d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t t; 9709d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t n; 9710d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t imm32; 9711d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool index; 9712d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool add; 9713d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice bool wback; 9714d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9715d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 9716d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9717d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9718d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9719d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice case eEncodingA1: 9720d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // if P == ‘0’ && W == ‘1’ then SEE STRT; 9721d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // if Rn == ‘1101’ && P == ‘1’ && U == ‘0’ && W == ‘1’ && imm12 == ‘000000000100’ then SEE PUSH; 9722d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9723d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice t = Bits32 (opcode, 15, 12); 9724d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice n = Bits32 (opcode, 19, 16); 9725d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice imm32 = Bits32 (opcode, 11, 0); 9726d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9727d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); 9728d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice index = BitIsSet (opcode, 24); 9729d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice add = BitIsSet (opcode, 23); 9730d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9731d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9732d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9733d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (wback && ((n == 15) || (n == t))) 9734d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9735d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9736d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice break; 9737d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9738d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice default: 9739d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9740d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice } 9741d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9742d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9743d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 9744d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!success) 9745d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9746d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9747d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice addr_t offset_addr; 9748d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (add) 9749d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice offset_addr = Rn + imm32; 9750d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice else 9751d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice offset_addr = Rn - imm32; 9752d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9753d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // address = if index then offset_addr else R[n]; 9754d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice addr_t address; 9755d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (index) 9756d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice address = offset_addr; 9757d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice else 9758d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice address = Rn; 9759d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9760d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice Register base_reg; 97611697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 9762d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice Register data_reg; 97631697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 9764d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice EmulateInstruction::Context context; 9765d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.type = eContextRegisterStore; 9766d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9767d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9768d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9769d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice uint32_t Rt = ReadCoreReg (t, &success); 9770d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!success) 9771d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9772d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9773d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (t == 15) 9774d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 9775e98b958df160cef9f2e816b4d86342f42a1c4025Caroline Tice uint32_t pc_value = ReadCoreReg (PC_REG, &success); 9776d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!success) 9777d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9778d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9779d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!MemUWrite (context, address, pc_value, addr_byte_size)) 9780d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9781d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice } 9782d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice else 9783d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 9784d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!MemUWrite (context, address, Rt, addr_byte_size)) 9785d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9786d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice } 9787d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9788d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice // if wback then R[n] = offset_addr; 9789d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (wback) 9790d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 9791d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.type = eContextAdjustBaseRegister; 9792d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice context.SetImmediate (offset_addr); 9793d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice 9794d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9795d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice return false; 9796d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9797d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9798d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9799d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9800d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9801d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.66 LDRD (immediate) 98021697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 98031697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 9804d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9805d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 9806d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9807d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 98081697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if ConditionPassed() then 98091697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 98101697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 98111697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice address = if index then offset_addr else R[n]; 98121697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice R[t] = MemA[address,4]; 98131697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice R[t2] = MemA[address+4,4]; 98141697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if wback then R[n] = offset_addr; 9815d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9816d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 98171697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool success = false; 9818d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9819d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9820d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 98211697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t t; 98221697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t t2; 98231697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t n; 98241697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t imm32; 98251697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool index; 98261697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool add; 98271697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice bool wback; 98281697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 9829d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9830d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 98311697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice case eEncodingT1: 98321697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if P == ‘0’ && W == ‘0’ then SEE “Related encodings”; 98331697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if Rn == ‘1111’ then SEE LDRD (literal); 98341697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); 98351697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t = Bits32 (opcode, 15, 12); 98361697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t2 = Bits32 (opcode, 11, 8); 98371697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice n = Bits32 (opcode, 19, 16); 98381697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 98391697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98401697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’); 98411697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice index = BitIsSet (opcode, 24); 98421697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice add = BitIsSet (opcode, 23); 98431697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice wback = BitIsSet (opcode, 21); 98441697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98451697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if wback && (n == t || n == t2) then UNPREDICTABLE; 98461697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (wback && ((n == t) || (n == t2))) 98471697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98481697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98491697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 98501697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (BadReg (t) || BadReg (t2) || (t == t2)) 98511697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98521697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98531697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice break; 98541697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98551697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice case eEncodingA1: 98561697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if Rn == ‘1111’ then SEE LDRD (literal); 98571697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if Rt<0> == ‘1’ then UNPREDICTABLE; 98581697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 98591697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t = Bits32 (opcode, 15, 12); 9860eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (BitIsSet (t, 0)) 9861eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 98621697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice t2 = t + 1; 98631697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice n = Bits32 (opcode, 19, 16); 98641697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 98651697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98661697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); 98671697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice index = BitIsSet (opcode, 24); 98681697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice add = BitIsSet (opcode, 23); 98691697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 98701697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98711697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if P == ‘0’ && W == ‘1’ then UNPREDICTABLE; 98721697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 98731697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98741697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98751697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if wback && (n == t || n == t2) then UNPREDICTABLE; 98761697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (wback && ((n == t) || (n == t2))) 98771697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98781697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98791697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if t2 == 15 then UNPREDICTABLE; 98801697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (t2 == 15) 98811697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98821697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98831697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice break; 98841697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98851697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice default: 98861697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98871697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice } 98881697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98891697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 98901697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 98911697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!success) 98921697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 98931697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 98941697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice addr_t offset_addr; 98951697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (add) 98961697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice offset_addr = Rn + imm32; 98971697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice else 98981697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice offset_addr = Rn - imm32; 98991697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99001697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //address = if index then offset_addr else R[n]; 99011697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice addr_t address; 99021697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (index) 99031697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice address = offset_addr; 99041697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice else 99051697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice address = Rn; 99061697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99071697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //R[t] = MemA[address,4]; 99081697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice Register base_reg; 99091697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 99101697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99111697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice EmulateInstruction::Context context; 99121697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.type = eContextRegisterLoad; 99131697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 99141697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99151697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 99161697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 99171697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!success) 99181697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 99191697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99201697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 99211697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 99221697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99231697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //R[t2] = MemA[address+4,4]; 99241697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99251697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 99261697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice data = MemARead (context, address + 4, addr_byte_size, 0, &success); 99271697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!success) 99281697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 99291697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99301697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 99311697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 99321697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99331697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice //if wback then R[n] = offset_addr; 99341697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (wback) 99351697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice { 99361697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.type = eContextAdjustBaseRegister; 99371697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice context.SetAddress (offset_addr); 99381697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice 99391697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 99401697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice return false; 9941d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9942d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9943d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9944d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9945d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9946d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.68 LDRD (register) 9947eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 9948eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 9949d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9950d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 9951d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9952d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9953eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if ConditionPassed() then 9954eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice EncodingSpecificOperations(); 9955eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 9956eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice address = if index then offset_addr else R[n]; 9957eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice R[t] = MemA[address,4]; 9958eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice R[t2] = MemA[address+4,4]; 9959eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if wback then R[n] = offset_addr; 9960d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9961d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9962eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool success = false; 9963d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9964d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9965d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9966eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t t; 9967eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t t2; 9968eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t n; 9969eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t m; 9970eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool index; 9971eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool add; 9972eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice bool wback; 9973d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9974d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9975d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9976eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice case eEncodingA1: 9977eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if Rt<0> == ‘1’ then UNPREDICTABLE; 9978eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 9979eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice t = Bits32 (opcode, 15, 12); 9980eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (BitIsSet (t, 0)) 9981eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 9982eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice t2 = t + 1; 9983eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice n = Bits32 (opcode, 19, 16); 9984eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice m = Bits32 (opcode, 3, 0); 9985d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9986eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); 9987eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice index = BitIsSet (opcode, 24); 9988eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice add = BitIsSet (opcode, 23); 9989eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9990d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9991eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE; 9992eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 9993eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 9994d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9995eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 9996eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 9997eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 9998d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9999eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10000eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (wback && ((n == 15) || (n == t) || (n == t2))) 10001eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10002d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10003eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10004eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if ((ArchVersion() < 6) && wback && (m == n)) 10005eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10006eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice break; 10007d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10008eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice default: 10009eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10010d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10011d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10012eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 10013eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10014eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10015eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice Register base_reg; 10016eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 10017d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10018eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 10019eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10020eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10021eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice Register offset_reg; 10022eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 10023d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10024eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10025eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice addr_t offset_addr; 10026eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (add) 10027eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_addr = Rn + Rm; 10028eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice else 10029eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice offset_addr = Rn - Rm; 10030d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10031eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // address = if index then offset_addr else R[n]; 10032eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice addr_t address; 10033eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (index) 10034eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice address = offset_addr; 10035eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice else 10036eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice address = Rn; 10037d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10038eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice EmulateInstruction::Context context; 10039eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.type = eContextRegisterLoad; 10040eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10041d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10042eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // R[t] = MemA[address,4]; 10043eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 10044eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10045eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10046eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10047d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10048eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10049eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10050d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10051eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // R[t2] = MemA[address+4,4]; 10052d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10053eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10054eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!success) 10055eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10056d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10057eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10058eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10059d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10060eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice // if wback then R[n] = offset_addr; 10061eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (wback) 10062d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 10063eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.type = eContextAdjustBaseRegister; 10064eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice context.SetAddress (offset_addr); 10065d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10066eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10067eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice return false; 10068d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10069d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 10070d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 10071d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10072d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10073d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10074d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.200 STRD (immediate) 10075d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 10076d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10077d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 10078d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 10079d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 10080d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10081d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 10082d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10083eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// if (ConditionPassed(opcode)) 10084eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// { 10085eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// switch (encoding) 10086eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// { 10087eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// } 10088eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// } 10089d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 10090d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10091d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10092d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10093d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.201 STRD (register) 10094d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 10095d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10096d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 10097d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 10098d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 10099d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10100d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 10101d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 10102eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// if (ConditionPassed(opcode)) 10103eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// { 10104eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// switch (encoding) 10105eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// { 10106eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// } 10107eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// } 1010824bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton return true; 10109d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 10110d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 101112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 101122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 1011364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 101142b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 101152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_arm_opcodes[] = 101162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 101172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 101182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 101192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 101202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 101229f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 101239f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 101242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 101269f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 10127864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 10128e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to ip 101299f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 101309f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 10131864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 101322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 10134864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 10135d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 101362b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push one register 101382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 101393e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 101402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 101429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 101439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 101442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 10146587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Epilogue instructions 101472b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 101482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101499f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 101509f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 101519b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 10152b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 10153b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 10154b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 10155b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 10156b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 101573b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 101583b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 101593b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 101603b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 101613b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 10162696b4effb53cac2ec14b54a65c695450b4d7f456Johnny Chen { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 10163383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // To resolve ambiguity, "blx <label>" should come before "bl <label>". 10164383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 10165383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 10166383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 10167ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 10168ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 1016959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // bxj 1017059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 10171b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 10172b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 1017328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // Data-processing instructions 1017428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 10175157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 10176157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 10177157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 10178157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 101798fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (immediate) 10180157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 101818fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (register) 10182157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 10183c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice // add (register-shifted register) 10184c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>m, <Rm>, <type> <RS>"}, 10185a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // adr 10186a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 10187a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 10188e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 10189157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 10190e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 10191157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 10192b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (immediate) 10193b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 10194b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (register) 10195b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 101962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 101972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 101982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 101992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 102007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 102017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 102027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 102037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 10204ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (immediate) 10205ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 10206ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (register) 10207ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 1020890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // rsc (immediate) 1020990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 1021090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // rsc (register) 1021190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 102129b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (immediate) 102139b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 102149b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (register) 102159b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 1021615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // sub (immediate, ARM) 1021715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 10218c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen // sub (sp minus immediate) 10219c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 102204cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // sub (register) 102214cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 102222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 102232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 102242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 102252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 10226de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 10227de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 10228de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 10229de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 10230de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 1023189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // mov (immediate) 1023289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 1023389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 1023401d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // mov (register) 1023501d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 10236d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 10237d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 10238d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 10239d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 102403847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (immediate) 102413847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 102423847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (register) 102433847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 1024434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 1024534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 1024634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) 1024734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 1024882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 1024982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 102502ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // asr (register) 10251e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 102522ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 102532ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 102542ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 102552ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 102562ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 102572ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 102582ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 102592ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 10260eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 10261eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 10262eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 10263eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 10264eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 10265eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 102665c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 102675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 1026828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 1026928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 10270b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 10271b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 102720b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 10273713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 1027485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 10275fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 102764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 10277fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 1027830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 102790491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 10280952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 102810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 10282a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 102835f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 10284672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 1028578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 10286291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 10287291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 102881697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 10289eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 10290fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 10291fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 10292fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 10293fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 102941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 10295b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 10296af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 102973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 102986bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 102998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 103005168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 10301ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 10302d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 103036bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 103046bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 103056bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // Other instructions 103066bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 10307868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 103088ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 1030911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 10310b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 10311b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 103121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 103132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 103142b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 103152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_arm_opcodes; ++i) 103172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 103182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 103192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_arm_opcodes[i]; 103202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 103212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 103222b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 103232b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 103262b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 10327347320d16d98cffaadf3f888569100c43b241068Johnny Chen{ 103282b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103292b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 103302b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_thumb_opcodes[] = 103312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 103322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 103332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 103342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 103352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103362b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 103379f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 103389f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 103399f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 103402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 103429f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 10343e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to r7 103449f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 10345e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 103469f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 103472b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 10348864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen // PC-relative load into register (see also EmulateADDSPRm) 10349c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 103502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103512b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 10352864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 10353c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 10354864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 10355864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 10356d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 103572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103582b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 10359d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 10360d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 103612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 103632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Epilogue instructions 103642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 103652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 10366e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 10367864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 103689f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 103699f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 103709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 10371d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 10372d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 10373b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 10374b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 10375b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 10376b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 10377c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 10378c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 10379c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 10380c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // If Then makes up to four following instructions conditional. 10381c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 103823b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 103833b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 103843b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 103853b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 103863b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 103873b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 103883b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 10389e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 103909ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 10391696b4effb53cac2ec14b54a65c695450b4d7f456Johnny Chen { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 10392383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 10393e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 10394383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 10395e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 10396383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 10397ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 10398ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 1039959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // bxj 1040059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 1040153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // compare and branch 1040253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 1040360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch byte 1040460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 1040560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch halfword 1040660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 10407b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 10408b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 1040926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Data-processing instructions 1041026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 10411157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 10412157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 10413157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 10414157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 10415157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10416157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // add (register) 104179f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 1041826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 104199f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 10420a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // adr 10421a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 10422a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 10423a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 10424e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 10425157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 10426e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 10427e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 10428e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10429b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (immediate) 10430b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 10431b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (register) 10432b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 10433b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 104342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 104352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 104362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 104372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 104382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 104397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 104407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 104417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 104427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 104437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10444ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (immediate) 10445ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 10446ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 10447ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (register) 10448ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 104499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (immediate) 104509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 104519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (register) 104529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 104539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10454dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // add (immediate, Thumb) 10455dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 10456dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 10457dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 10458dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 1045915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // sub (immediate, Thumb) 1046015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 1046115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 1046215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 1046315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 10464c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen // sub (sp minus immediate) 10465c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 10466c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 104674cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice // sub (register) 104684cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 104694cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 104702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 104712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 104722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 104732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 10474de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 104752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 10476de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 10477de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 10478de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 10479de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 104807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 10481338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from high register to high register 104829f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 10483338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from low register to low register 104849f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 104857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // mov{s}<c>.w <Rd>, <Rm> 104867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 10487357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // move immediate 104889f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 104899f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 1049089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 10491d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 10492d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 10493d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 10494d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 10495d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 1049634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (immediate) 10497688926f8fb9a56964249ec970b4ae313a5b366d4Johnny Chen { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 1049834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (register) 1049934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 10500078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 1050134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 1050234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 10503078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 1050434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm both from r0-r7) 1050534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 1050634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm not both from r0-r7) 1050734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 1050882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 1050982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 105104d896db529a5fef200333ef673976528319279bdJohnny Chen { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 10511e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // asr (register) 10512e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 10513e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 105142ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 105152ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 105162ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 105172ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 105182ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 105192ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 105202ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 105212ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 105222ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 105232ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 10524eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 105252ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 10526eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 10527eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 10528eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 10529eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 10530eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 10531eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 10532eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 105335c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 105345c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 105355c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 105365c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 105376bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 1053826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 10539b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 10540b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 10541b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 105420b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 10543ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 10544baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 10545baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 10546baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 10547baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 10548baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // Thumb2 PC-relative load into register 10549fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 10550fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 10551fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 1055221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 1055321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 1055421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[>Rn>, #+/-<imm8>]{!}" }, 10555f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 1055630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 10557ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, eSize32,&EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 105580491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 105590491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 105600491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 10561952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 105620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 105630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 10564a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 10565a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 105665f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 10567672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 10568672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 1056978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 1057078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 10571d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 10572291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 10573291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 105741697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt?, <Rt2>, [<Rn>,#+/-<imm>]!"}, 10575fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 10576fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 10577fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 10578fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 10579fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 10580b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 105817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 10582fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 10583fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 10584fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 10585fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 10586fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 10587fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 10588fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 10589fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 105906bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 105918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 105928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 105935168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 105946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 105956bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 105966bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // Other instructions 105976bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 105986bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 10599868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 10600868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 106018ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 106028ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 1060311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 1060411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 10605b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 10606b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xffd00000, 0xe8100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 10607b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xffd00000, 0xe9900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" } 106086bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 106092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 106102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 106112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 106122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_thumb_opcodes; ++i) 106132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 106142b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 106152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_thumb_opcodes[i]; 106162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 106172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 106182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1061964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1062031e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool 10621395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 1062231e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{ 1062331e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton m_arm_isa = 0; 10624940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton const char *arch_cstr = arch.GetArchitectureName (); 10625395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (arch_cstr) 10626395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton { 10627395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 10628395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 10629395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 10630395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 10631395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 10632395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 10633395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 10634395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 10635395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 10636395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 1063731e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton } 1063831e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton return m_arm_isa != 0; 1063931e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton} 1064031e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 1064131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 1064264c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 1064364c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction () 1064464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 1064564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 10646b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 1064764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1064864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 1064964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 1065064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1065164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 106529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Context read_inst_context; 106539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.type = eContextReadOpcode; 106549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.SetNoArgs (); 106559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 10656b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_cpsr & MASK_CPSR_T) 1065764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10658b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeThumb; 10659cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 1066064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1066164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1066264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 106637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 1066464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 106657bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode16 (thumb_opcode); 1066664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1066764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 1066864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 106697bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 1067064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1067164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1067264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1067364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 1067464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10675b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeARM; 106767bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 1067764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1067864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1067964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1068064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 1068164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10682b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeInvalid; 10683b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_pc = LLDB_INVALID_ADDRESS; 1068464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1068564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return success; 1068664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 1068764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 10688ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t 10689ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion () 10690ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10691ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return m_arm_isa; 10692ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10693ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 1069464c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 106957bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::ConditionPassed (const uint32_t opcode) 1069664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 10697b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_cpsr == 0) 1069864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1069964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 107007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton const uint32_t cond = CurrentCond (opcode); 1070164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1070264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond == UINT32_MAX) 1070364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1070464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1070564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool result = false; 1070664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton switch (UnsignedBits(cond, 3, 1)) 1070764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10708b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 0: result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; break; 10709b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 1: result = (m_opcode_cpsr & MASK_CPSR_C) != 0; break; 10710b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 2: result = (m_opcode_cpsr & MASK_CPSR_N) != 0; break; 10711b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 3: result = (m_opcode_cpsr & MASK_CPSR_V) != 0; break; 10712b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 4: result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); break; 1071364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 5: 1071464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10715b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool n = (m_opcode_cpsr & MASK_CPSR_N); 10716b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool v = (m_opcode_cpsr & MASK_CPSR_V); 1071764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = n == v; 1071864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1071964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1072064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 6: 1072164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10722b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool n = (m_opcode_cpsr & MASK_CPSR_N); 10723b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool v = (m_opcode_cpsr & MASK_CPSR_V); 10724b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 1072564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1072664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1072764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 7: 1072864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = true; 1072964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1073064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1073164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1073264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond & 1) 1073364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = !result; 1073464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return result; 1073564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 1073664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 107379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t 107387bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::CurrentCond (const uint32_t opcode) 107399ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 10740b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton switch (m_opcode_mode) 107419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 107429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 107439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeInvalid: 107449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 107459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 107469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeARM: 107477bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return UnsignedBits(opcode, 31, 28); 107489ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 107499ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeThumb: 107509ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 107519ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // 'cond' field of the encoding. 107529ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 107537bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton const uint32_t byte_size = m_opcode.GetByteSize(); 107547bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (byte_size == 2) 107557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 107567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 107577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return Bits32(opcode, 11, 7); 107587bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 107597bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton else 107607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 107617bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton assert (byte_size == 4); 107627bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (Bits32(opcode, 31, 27) == 0x1e && 107637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 15, 14) == 0x02 && 107647bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 12, 12) == 0x00 && 107657bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 25, 22) <= 0x0d) 107667bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 107677bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return Bits32(opcode, 25, 22); 107687bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 107697bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 107707bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 107717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return m_it_session.GetCond(); 107729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 107739ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 107749ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return UINT32_MAX; // Return invalid value 107759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 107769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 107779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 10778098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock() 10779098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 10780098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 10781098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 10782098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 10783098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 10784098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock() 10785098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 10786098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 10787098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 10788098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 10789b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 10790b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::BadMode (uint32_t mode) 10791b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 10792b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10793b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice switch (mode) 10794b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10795b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 16: return false; // '10000' 10796b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 17: return false; // '10001' 10797b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 18: return false; // '10010' 10798b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 19: return false; // '10011' 10799b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 22: return false; // '10110' 10800b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 23: return false; // '10111' 10801b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 27: return false; // '11011' 10802b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 31: return false; // '11111' 10803b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice default: return true; 10804b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10805b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 10806b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 10807b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10808b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 10809b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CurrentModeIsPrivileged () 10810b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 10811b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 10812b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10813b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BadMode (mode)) 10814b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 10815b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10816b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (mode == 16) 10817b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 10818b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10819b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 10820b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 10821b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10822b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticevoid 10823b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 10824b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 10825b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool privileged = CurrentModeIsPrivileged(); 10826b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10827b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint32_t tmp_cpsr = 0; 10828b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10829b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton tmp_cpsr = tmp_cpsr | (Bits32 (m_opcode_cpsr, 23, 20) << 20); 10830b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10831b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 3)) 10832b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10833b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 10834b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 10835b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 10836b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10837b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10838b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 2)) 10839b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10840b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 10841b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10842b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10843b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 1)) 10844b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10845b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 10846b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 10847b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 10848b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 10849b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 10850b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10851b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10852b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 0)) 10853b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10854b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 10855b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 10856b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 10857b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 10858b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 10859b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 10860b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10861b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10862b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_cpsr = tmp_cpsr; 10863b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 10864b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10865b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10866098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 108679ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 108689ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 108699ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 108709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 10871ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Check the current instruction set. 10872ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (CurrentInstrSet() == eModeARM) 108739ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 10874ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 108759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 10876ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 108779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1087853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 1087953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 1088053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 108819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 108829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 108839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 108849ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 10885668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 108869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 108879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 108880f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 108890f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // we want to record it and issue a WriteRegister callback so the clients 108900f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // can track the mode changes accordingly. 108910f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen bool cpsr_changed = false; 108929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 108939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (BitIsSet(addr, 0)) 108949ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 108950f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeThumb) 108960f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 108970f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeThumb); 108980f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 108990f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 109009ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 10901668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetMode (eModeThumb); 109029ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 109039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else if (BitIsClear(addr, 1)) 109049ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 109050f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeARM) 109060f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 109070f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeARM); 109080f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 109090f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 109109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 10911668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetMode (eModeARM); 109129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 109139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else 109149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; // address<1:0> == '10' => UNPREDICTABLE 109159ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 109160f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (cpsr_changed) 109170f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 10918558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 109190f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen return false; 109200f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 109219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1092253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 1092353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 1092453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 109259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 1092664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 10927ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 10928ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 10929668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 10930ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10931ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (ArchVersion() >= ARMv5T) 10932668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 10933ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 10934ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return BranchWritePC((const Context)context, addr); 10935ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10936ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 1093726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 1093826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 10939668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 1094026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 1094126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 10942668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 1094326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 1094426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return BranchWritePC((const Context)context, addr); 1094526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 1094626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 10947ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode 10948ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet () 10949ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10950b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton return m_opcode_mode; 10951ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10952ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 10953b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 10954558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed. This function has a side effect of updating 10955558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary. 10956ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 10957ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 10958ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10959b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 10960ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen switch (arm_or_thumb) 10961ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen { 10962ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen default: 10963ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return false; 10964ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen eModeARM: 10965ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Clear the T bit. 10966558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr &= ~MASK_CPSR_T; 10967ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 10968ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen eModeThumb: 10969ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Set the T bit. 10970558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr |= MASK_CPSR_T; 10971ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 10972ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen } 10973ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return true; 10974ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10975ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 10976ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for 10977ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 10978ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 10979ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 10980ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport() 10981ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 10982ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return (ArchVersion() >= ARMv7); 10983ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 10984ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 10985bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information 10986bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions. This status 10987bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions. 10988bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult 10989bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 10990bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{ 10991bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint32_t result; 10992bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t carry_out; 10993bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t overflow; 10994bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 10995bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint64_t unsigned_sum = x + y + carry_in; 10996bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 10997bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 10998bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen result = UnsignedBits(unsigned_sum, 31, 0); 10999bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen carry_out = (result == unsigned_sum ? 0 : 1); 11000bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen overflow = ((int32_t)result == signed_sum ? 0 : 1); 11001bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 11002bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen AddWithCarryResult res = { result, carry_out, overflow }; 11003bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen return res; 11004bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen} 11005bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 11006157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenuint32_t 11007e39f22d1a369866808b8739c3cec15063d806833Johnny ChenEmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 11008157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 11009e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_kind, reg_num; 11010e39f22d1a369866808b8739c3cec15063d806833Johnny Chen switch (num) 11011157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 11012e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case SP_REG: 11013e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 11014e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 11015e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 11016e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case LR_REG: 11017e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 11018e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 11019e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 11020e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case PC_REG: 11021e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 11022e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_PC; 11023e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 11024e39f22d1a369866808b8739c3cec15063d806833Johnny Chen default: 110254fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton if (num < SP_REG) 11026e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 11027e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindDWARF; 11028e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = dwarf_r0 + num; 11029e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 11030157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 11031e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 11032e39f22d1a369866808b8739c3cec15063d806833Johnny Chen assert(0 && "Invalid register number"); 11033e39f22d1a369866808b8739c3cec15063d806833Johnny Chen *success = false; 110344fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton return UINT32_MAX; 11035e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 11036e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 11037e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 11038e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 11039e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // Read our register. 11040e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 11041e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 11042e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing an ARM instruction , PC reads as the address of the current 11043e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 8. 11044e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing a Thumb instruction , PC reads as the address of the current 11045e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 4. 11046e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (num == 15) 11047e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 11048e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (CurrentInstrSet() == eModeARM) 11049157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen val += 8; 11050e39f22d1a369866808b8739c3cec15063d806833Johnny Chen else 11051e39f22d1a369866808b8739c3cec15063d806833Johnny Chen val += 4; 11052157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 11053157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 11054157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return val; 11055157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 11056157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 11057ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the 11058ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result. 11059ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 11060ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 11061ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual: 11062ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 11063ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then // Can only occur for encoding A1 11064ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ALUWritePC(result); // setflags is always FALSE here 11065ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else 11066ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// R[d] = result; 11067ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if setflags then 11068ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.N = result<31>; 11069ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.Z = IsZeroBit(result); 11070ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.C = carry; 11071ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// // APSR.V unchanged 11072ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 11073ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which 11074ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u. 11075ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool 1107610530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 1107710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 1107810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t Rd, 1107910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen bool setflags, 1108010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 1108110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 11082ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{ 11083ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (Rd == 15) 11084ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 11085ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (!ALUWritePC (context, result)) 11086ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 11087ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 11088ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen else 11089ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 11090a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t reg_kind, reg_num; 11091a695f958db37c102d480a9c0780abec262ba8332Johnny Chen switch (Rd) 11092a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 11093a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case SP_REG: 11094a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindGeneric; 11095a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 11096a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 11097a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case LR_REG: 11098a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindGeneric; 11099a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 11100a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 11101a695f958db37c102d480a9c0780abec262ba8332Johnny Chen default: 11102a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindDWARF; 11103a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = dwarf_r0 + Rd; 11104a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 11105a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 11106ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 11107ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (setflags) 1110810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return WriteFlags (context, result, carry, overflow); 1110910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen } 1111010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return true; 1111110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen} 1111210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 1111310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 1111410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual: 1111510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 1111610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>; 1111710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result); 1111810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry; 1111910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow 1112010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 1112110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means 1112210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags. 1112310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool 1112410530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context, 1112510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 1112610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 1112710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 1112810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{ 11129b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 1113024348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 1113124348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1113210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (carry != ~0u) 1113324348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 1113410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (overflow != ~0u) 1113524348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 11136b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_new_inst_cpsr != m_opcode_cpsr) 1113710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen { 1113810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1113910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 11140ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 11141ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return true; 11142ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen} 11143ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 1114464c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 1114564c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::EvaluateInstruction () 1114664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 11147c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // Advance the ITSTATE bits to their values for the next instruction. 11148b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 11149c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.ITAdvance(); 11150c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 1115164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1115264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 11153