EmulateInstructionARM.cpp revision d05b4903bb95b07e709986961fe387921dd0e029
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) 13259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 1336bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 1349b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 1352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 1360e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1380e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation 1390e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// 1400e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//---------------------------------------------------------------------- 1410e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen 1422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1432b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize () 1447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{ 1452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1467dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen 1472b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid 1482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate () 14964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 1502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1512b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 152fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 153fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 154fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 155fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 1569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 1589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 159fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 160fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t random_data = rand (); 161fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 162fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 163cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address, random_data, addr_byte_size)) 164fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 165fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 166fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 167fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 168fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 169713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 170713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 171713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n) 172713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 1739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 1759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 176713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 17762ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen bool success; 178713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 179713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 180713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 181713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 182713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 183713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 184713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 185713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 186713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 187713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 188713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 18908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to 19008c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates 19108c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data. 1922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 1937bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 19464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 19564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0 19664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton // ARM pseudo code... 19764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (ConditionPassed()) 19864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 19964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton EncodingSpecificOperations(); 20064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton NullCheckIfThumbEE(13); 20164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = SP - 4*BitCount(registers); 20264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 20364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i = 0 to 14) 20464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 205bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (registers<i> == '1') 20664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 20764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 20864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = bits(32) UNKNOWN; 20964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 21064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = R[i]; 21164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton address = address + 4; 21264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 21464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 215bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (registers<15> == '1') // Only possible for encoding A1 or A2 21664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton MemA[address,4] = PCStoreValue(); 21764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 21864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton SP = SP - 4*BitCount(registers); 21964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 22064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif 22164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 22264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 2237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 22464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 226e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 22764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 22864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 2293c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen uint32_t registers = 0; 23091d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 2313c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen switch (encoding) { 232aedde1c6a33b123031499800f56954adc86058f5Johnny Chen case eEncodingT1: 233108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 7, 0); 234aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // The M bit represents LR. 235bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 236ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 14); 237aedde1c6a33b123031499800f56954adc86058f5Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 238aedde1c6a33b123031499800f56954adc86058f5Johnny Chen if (BitCount(registers) < 1) 239aedde1c6a33b123031499800f56954adc86058f5Johnny Chen return false; 240aedde1c6a33b123031499800f56954adc86058f5Johnny Chen break; 2417dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT2: 2427dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // Ignore bits 15 & 13. 243108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0) & ~0xa000; 2447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BitCount(registers) < 2 then UNPREDICTABLE; 2457dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen if (BitCount(registers) < 2) 2467dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 2477dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 2487dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen case eEncodingT3: 249108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 2507dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if BadReg(t) then UNPREDICTABLE; 25191d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (BadReg(Rt)) 2527dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen return false; 25391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 2547dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen break; 2553c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA1: 256108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen registers = Bits32(opcode, 15, 0); 257a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // Instead of return false, let's handle the following case as well, 258a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // which amounts to pushing one reg onto the full descending stacks. 259a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 2603c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 2613c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen case eEncodingA2: 262108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 2637dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen // if t == 13 then UNPREDICTABLE; 26491d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt == dwarf_sp) 2653c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen return false; 26691d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen registers = (1u << Rt); 2673c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen break; 268ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 269ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 2703c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen } 271ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 27264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t addr = sp - sp_offset; 27364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton uint32_t i; 27464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 2769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 2779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 2789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 2792b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice Register sp_reg; 2802b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 28164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton for (i=0; i<15; ++i) 28264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2837c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 28464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_r0 + i; 2862b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetRegisterToRegisterPlusOffset (dwarf_reg, sp_reg, addr - sp); 287e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(i, &success); 28864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 28964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 290cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 29164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 29264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr += addr_byte_size; 29364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 29464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 29564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 2967c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 29764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 2989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_pc; 2999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 300e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 30164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 30264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 303e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (!MemAWrite (context, addr, pc, addr_byte_size)) 30464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 30564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 30664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 30764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton context.type = EmulateInstruction::eContextAdjustStackPointer; 3089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 30964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 3102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 31164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 31264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 31364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return true; 31464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 31564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 316ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from 317ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates 318ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data. 3192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 3207bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 321ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{ 322ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0 323ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // ARM pseudo code... 324ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (ConditionPassed()) 325ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 326ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(13); 327ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen address = SP; 328ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for i = 0 to 14 329bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 330ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 331bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 332ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if UnalignedAllowed then 333ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemU[address,4]); 334ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen else 335ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen LoadWritePC(MemA[address,4]); 336bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<13> == '0' then SP = SP + 4*BitCount(registers); 337bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<13> == '1' then SP = bits(32) UNKNOWN; 338ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 339ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif 340ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 341ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen bool success = false; 342ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 3437bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 344ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 3452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 346e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 347ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 348ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 349ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t registers = 0; 350ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t Rt; // the destination register 351ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen switch (encoding) { 352ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT1: 353ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 7, 0); 354ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // The P bit represents PC. 355bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (Bit32(opcode, 8)) 356ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers |= (1u << 15); 357ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 1 then UNPREDICTABLE; 358ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (BitCount(registers) < 1) 359ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 360ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 361ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT2: 362ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Ignore bit 13. 363ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0) & ~0x2000; 364ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 365bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 366ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 367098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 368098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 369098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 370ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 371ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingT3: 372ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 373ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 374098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 13) 375098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return false; 376098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 377ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 378ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 379ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 380ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA1: 381ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = Bits32(opcode, 15, 0); 382ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // Instead of return false, let's handle the following case as well, 383ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // which amounts to popping one reg from the full descending stacks. 384ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 385ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 386bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 387098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 388ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 389ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 390ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen case eEncodingA2: 391ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen Rt = Bits32(opcode, 15, 12); 392ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen // if t == 13 then UNPREDICTABLE; 393ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (Rt == dwarf_sp) 394ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 395ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen registers = (1u << Rt); 396ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen break; 397ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen default: 398ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 399ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 400ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t sp_offset = addr_byte_size * BitCount (registers); 401ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr_t addr = sp; 402ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen uint32_t i, data; 403ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 4059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 4069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 4079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 4088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register sp_reg; 4098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 410ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen for (i=0; i<15; ++i) 411ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 4127c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, i)) 413ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 4149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_r0 + i; 4158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 416cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, 4, 0, &success); 417ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 418ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 4199bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 420ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 421ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr += addr_byte_size; 422ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 423ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 424ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4257c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen if (BitIsSet (registers, 15)) 426ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen { 4279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.num = dwarf_pc; 4288ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 429cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, 4, 0, &success); 430ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen if (!success) 431ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 432f3eaacfc02d0a98d3bac1eaef74ad5c1c66ccfdcJohnny Chen // In ARMv5T and above, this is an interworking branch. 433668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 434ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 435ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen addr += addr_byte_size; 436ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 437ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 438ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 4399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 440ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 442ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return false; 443ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen } 444ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen return true; 445ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen} 446ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen 4475b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// Set r7 or ip to point to saved value residing within the stack. 448bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen// ADD (SP plus immediate) 4492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 4507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 451bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{ 452bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0 453bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen // ARM pseudo code... 454bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (ConditionPassed()) 455bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 456bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen EncodingSpecificOperations(); 457bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 458bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if d == 15 then 459bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 460bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen else 461bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen R[d] = result; 462bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if setflags then 463bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.N = result<31>; 464bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.Z = IsZeroBit(result); 465bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.C = carry; 466bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen APSR.V = overflow; 467bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 468bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#endif 469bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 470bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen bool success = false; 471bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 4727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 473bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen { 474e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 475bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen if (!success) 476bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 477bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t Rd; // the destination register 478bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen uint32_t imm32; 479bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen switch (encoding) { 480bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingT1: 481bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = 7; 482bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 483bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 484bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen case eEncodingA1: 485bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen Rd = Bits32(opcode, 15, 12); 486bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 487bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen break; 488bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen default: 489bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 490bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 491bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t sp_offset = imm32; 492bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen addr_t addr = sp + sp_offset; // a pointer to the stack area 493bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 4949bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 4959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 4969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register sp_reg; 4979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 4989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, sp_offset); 499bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 5002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 501bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return false; 502bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen } 503bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen return true; 504bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen} 505bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen 5062ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer. 5072ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register) 5082b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5097bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 5102ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{ 5112ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0 5122ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // ARM pseudo code... 5132ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (ConditionPassed()) 5142ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 5152ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen EncodingSpecificOperations(); 5162ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen result = R[m]; 5172ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if d == 15 then 5182ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5192ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen else 5202ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen R[d] = result; 5212ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if setflags then 5222ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.N = result<31>; 5232ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen APSR.Z = IsZeroBit(result); 5242ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.C unchanged 5252ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen // APSR.V unchanged 5262ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5272ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif 5282ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5292ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen bool success = false; 5302ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5322ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen { 533e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 5342ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen if (!success) 5352ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5362ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen uint32_t Rd; // the destination register 5372ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen switch (encoding) { 5382ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingT1: 5392ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 7; 5402ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 5412ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen case eEncodingA1: 5422ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen Rd = 12; 5432ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen break; 5442ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen default: 5452ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5462ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 5489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 5499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 5509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register sp_reg; 5519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 5529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (sp_reg, 0); 5532ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5542b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 5552ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return false; 5562ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen } 5572ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen return true; 5582ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen} 5592ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen 5601c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7). 5611c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register) 5622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 5637bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 5641c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{ 5657bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdRm (opcode, encoding); 566338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen} 567338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen 568338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register. 569338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register) 570338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool 5717bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 572338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{ 5731c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0 5741c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // ARM pseudo code... 5751c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (ConditionPassed()) 5761c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 5771c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen EncodingSpecificOperations(); 5781c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen result = R[m]; 5791c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if d == 15 then 5801c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5811c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen else 5821c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen R[d] = result; 5831c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if setflags then 5841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.N = result<31>; 5851c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen APSR.Z = IsZeroBit(result); 5861c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.C unchanged 5871c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // APSR.V unchanged 5881c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 5891c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif 5901c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 5911c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen bool success = false; 5921c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 5937bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5941c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen { 5951c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rm; // the source register 5961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen uint32_t Rd; // the destination register 597338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen bool setflags; 5981c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen switch (encoding) { 5991c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen case eEncodingT1: 6007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 6011c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen Rm = Bits32(opcode, 6, 3); 602338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = false; 6037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 6047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 605338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen break; 606338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen case eEncodingT2: 6077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 2, 0); 608338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen Rm = Bits32(opcode, 5, 3); 609338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen setflags = true; 6107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (InITBlock()) 6117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6121c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen break; 6137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT3: 6147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 6157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 6167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 6177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 6187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (setflags && (BadReg(Rd) || BadReg(Rm))) 6197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 6207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 6217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 6227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 623ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 62401d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen case eEncodingA1: 62501d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen Rd = Bits32(opcode, 15, 12); 62601d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen Rm = Bits32(opcode, 3, 0); 62701d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen setflags = BitIsSet(opcode, 20); 62801d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 62901d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 63001d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen if (Rd == 15 && setflags) 63101d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen return false; 63201d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen break; 6331c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen default: 6341c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 6367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = ReadCoreReg(Rm, &success); 6371c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen if (!success) 6381c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return false; 6391c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 6401c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen // The context specifies that Rm is to be moved into Rd. 6419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 6422b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.type = EmulateInstruction::eContextRegisterLoad; 6439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 6449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 6452b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetRegister (dwarf_reg); 646ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 64710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 648ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 6491c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen } 6501c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen return true; 6511c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen} 6521c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen 653357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register. It 654357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value. 655357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate) 656357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool 6577bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 658357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{ 659357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0 660357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // ARM pseudo code... 661357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if (ConditionPassed()) 662357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 663357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen EncodingSpecificOperations(); 664357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen result = imm32; 665357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if d == 15 then // Can only occur for ARM encoding 666357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen ALUWritePC(result); // setflags is always FALSE here 667357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen else 668357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen R[d] = result; 669357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen if setflags then 670357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.N = result<31>; 671357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.Z = IsZeroBit(result); 672357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen APSR.C = carry; 673357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // APSR.V unchanged 674357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 675357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif 676357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 6777bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 678357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen { 679357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t Rd; // the destination register 680357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the immediate value to be written to Rd 681357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 682357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen bool setflags; 683357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen switch (encoding) { 68489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT1: 68589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32(opcode, 10, 8); 68689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = !InITBlock(); 68789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 68889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice carry = APSR_C; 68989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 69089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 69189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 69289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT2: 69389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32(opcode, 11, 8); 69489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = BitIsSet(opcode, 20); 69589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 69689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (BadReg(Rd)) 69789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 69889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 69989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 70089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 70189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingT3: 70289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 70389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 70489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 11, 8); 70589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = false; 70689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm4 = Bits32 (opcode, 19, 16); 70789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm3 = Bits32 (opcode, 14, 12); 70889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t i = Bit32 (opcode, 26); 70989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm8 = Bits32 (opcode, 7, 0); 71089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 71189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 71289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if BadReg(d) then UNPREDICTABLE; 71389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (BadReg (Rd)) 71489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 71589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice } 71689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 71789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 71889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingA1: 71989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 72089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 72189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 15, 12); 72289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = BitIsSet (opcode, 20); 72389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 72489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 72589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 72689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 72789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice case eEncodingA2: 72889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 72989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 73089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice Rd = Bits32 (opcode, 15, 12); 73189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice setflags = false; 73289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm4 = Bits32 (opcode, 19, 16); 73389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice uint32_t imm12 = Bits32 (opcode, 11, 0); 73489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice imm32 = (imm4 << 12) | imm12; 73589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 73689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // if d == 15 then UNPREDICTABLE; 73789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice if (Rd == 15) 73889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice return false; 73989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice } 74089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice break; 74189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice 74289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice default: 7439798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen return false; 744357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 745357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t result = imm32; 746357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 747357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // The context specifies that an immediate is to be moved into Rd. 7489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 7499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 7509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 751ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 75210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 753ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 754357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen } 755357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen return true; 756357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen} 757357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen 7585c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 7595c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// register. These 32 bits do not depend on whether the source register values are considered to be signed values or 7605c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// unsigned values. 7615c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// 7625c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 7635c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// limited to only a few forms of the instruction. 7645c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Ticebool 7657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 7665c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice{ 7675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#if 0 7685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ConditionPassed() then 7695c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice EncodingSpecificOperations(); 7705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 7715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 7725c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice result = operand1 * operand2; 7735c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice R[d] = result<31:0>; 7745c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if setflags then 7755c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.N = result<31>; 7765c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.Z = IsZeroBit(result); 7775c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ArchVersion() == 4 then 7785c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice APSR.C = bit UNKNOWN; 7795c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // else APSR.C unchanged 7805c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.V always unchanged 7815c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#endif 7825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 7837bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7845c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 7855c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t d; 7865c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t n; 7875c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint32_t m; 7885c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice bool setflags; 7895c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 7905c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // EncodingSpecificOperations(); 7915c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice switch (encoding) 7925c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 7935c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingT1: 7945c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 7955c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 2, 0); 7965c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 5, 3); 7975c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 2, 0); 7985c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = !InITBlock(); 7995c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8005c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 8015c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((ArchVersion() < ARMv6) && (d == n)) 8025c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8035c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8045c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 8055c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8065c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingT2: 8075c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 8085c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 11, 8); 8095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 19, 16); 8105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 3, 0); 8115c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = false; 8125c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8135c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 8145c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (BadReg (d) || BadReg (n) || BadReg (m)) 8155c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8165c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8175c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 8185c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8195c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice case eEncodingA1: 820bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 8215c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice d = Bits32 (opcode, 19, 16); 8225c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice n = Bits32 (opcode, 3, 0); 8235c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice m = Bits32 (opcode, 11, 8); 8245c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice setflags = BitIsSet (opcode, 20); 8255c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8265c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 8275c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((d == 15) || (n == 15) || (m == 15)) 8285c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8295c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8305c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 8315c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if ((ArchVersion() < ARMv6) && (d == n)) 8325c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8335c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8345c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice break; 8355c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8365c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice default: 8375c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8385c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8397bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 8407bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 8417bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 8425c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 8435c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8445c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!success) 8455c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8465c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8475c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 8485c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8495c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!success) 8505c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8515c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8525c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // result = operand1 * operand2; 8535c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice uint64_t result = operand1 * operand2; 8545c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8555c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // R[d] = result<31:0>; 8565c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice Register op1_reg; 8575c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice Register op2_reg; 8585c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 8595c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 8605c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8615c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice EmulateInstruction::Context context; 8625c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice context.type = eContextMultiplication; 8635c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice context.SetRegisterRegisterOperands (op1_reg, op2_reg); 8645c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8655c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 8665c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if setflags then 8695c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (setflags) 8705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 8715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.N = result<31>; 8725c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.Z = IsZeroBit(result); 873b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 8745c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 8755c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 876b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_new_inst_cpsr != m_opcode_cpsr) 8775c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 8785c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 8795c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return false; 8805c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8815c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 8825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // if ArchVersion() == 4 then 8835c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // APSR.C = bit UNKNOWN; 8845c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8855c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice } 8865c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice return true; 8875c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice} 8885c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice 889d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 890d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the value. 89128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool 8927bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 89328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{ 89428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0 89528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // ARM pseudo code... 89628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if (ConditionPassed()) 89728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen { 89828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen EncodingSpecificOperations(); 89928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen result = NOT(imm32); 90028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if d == 15 then // Can only occur for ARM encoding 90128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen ALUWritePC(result); // setflags is always FALSE here 90228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen else 90328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen R[d] = result; 90428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen if setflags then 90528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.N = result<31>; 90628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.Z = IsZeroBit(result); 90728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen APSR.C = carry; 90828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // APSR.V unchanged 90928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen } 91028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif 91133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 9127bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 91333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen { 91433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t Rd; // the destination register 915357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 916357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 91733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen bool setflags; 91833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen switch (encoding) { 91933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingT1: 92033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 11, 8); 92133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 922d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 92333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 92433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen case eEncodingA1: 92533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen Rd = Bits32(opcode, 15, 12); 92633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen setflags = BitIsSet(opcode, 20); 927d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 928d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 929d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 930d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (Rd == 15 && setflags) 931d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 93233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen break; 93333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen default: 93433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return false; 93533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 93633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen uint32_t result = ~imm32; 93733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen 93833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen // The context specifies that an immediate is to be moved into Rd. 9399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 9409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 9419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 942ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 94310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 944ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 94533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen } 94633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen return true; 94728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen} 94828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 949d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 950d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the result. 951d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chenbool 9527bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 953d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen{ 954d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#if 0 955d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // ARM pseudo code... 956d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (ConditionPassed()) 957d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 958d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EncodingSpecificOperations(); 959d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 960d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen result = NOT(shifted); 961d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if d == 15 then // Can only occur for ARM encoding 962d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ALUWritePC(result); // setflags is always FALSE here 963d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen else 964d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen R[d] = result; 965d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if setflags then 966d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.N = result<31>; 967d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.Z = IsZeroBit(result); 968d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen APSR.C = carry; 969d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // APSR.V unchanged 970d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 971d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#endif 972d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 9737bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 974d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 975d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rm; // the source register 976d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t Rd; // the destination register 977d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen ARM_ShifterType shift_t; 978d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 979d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen bool setflags; 980d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t carry; // the carry bit after the shift operation 981d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen switch (encoding) { 982d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT1: 983d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 2, 0); 984d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 5, 3); 985d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = !InITBlock(); 986d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_t = SRType_LSL; 987d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen shift_n = 0; 988d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (InITBlock()) 989d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 990d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 991d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingT2: 992d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 11, 8); 993d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 994d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 9953dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 996d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 997ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rm)) 998d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 999ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 1000d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen case eEncodingA1: 1001d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rd = Bits32(opcode, 15, 12); 1002d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen Rm = Bits32(opcode, 3, 0); 1003d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen setflags = BitIsSet(opcode, 20); 10043dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 1005d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen break; 1006d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen default: 1007d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1008d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 10097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1010d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t value = ReadCoreReg(Rm, &success); 1011d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!success) 1012d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1013d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1014d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry); 1015d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen uint32_t result = ~shifted; 1016d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1017d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // The context specifies that an immediate is to be moved into Rd. 1018d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen EmulateInstruction::Context context; 1019d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.type = EmulateInstruction::eContextImmediate; 1020d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen context.SetNoArgs (); 1021d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1022d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1023d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return false; 1024d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen } 1025d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen return true; 1026d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen} 1027d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen 1028788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register). 1029788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal) 10302b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 10317bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1032788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{ 1033788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0 1034788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen // ARM pseudo code... 1035788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (ConditionPassed()) 1036788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 1037788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1038788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen base = Align(PC,4); 1039788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen address = if add then (base + imm32) else (base - imm32); 1040788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen data = MemU[address,4]; 1041788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if t == 15 then 1042bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1043bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 1044788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = data; 1045788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else // Can only apply before ARMv7 1046788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 1047788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = ROR(data, 8*UInt(address<1:0>)); 1048788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen else 1049788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen R[t] = bits(32) UNKNOWN; 1050788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1051788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif 1052788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 10537bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1054788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen { 10557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1056e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1057788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 1058788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 1059809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen 1060809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen // PC relative immediate load context 10619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 10629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 10639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register pc_reg; 10649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 10659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 0); 10669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 1067c9de910d61f0471d18fced716fc10681ef432010Johnny Chen uint32_t Rt; // the destination register 1068788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t imm32; // immediate offset from the PC 1069c9de910d61f0471d18fced716fc10681ef432010Johnny Chen bool add; // +imm32 or -imm32? 1070c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t base; // the base address 1071c9de910d61f0471d18fced716fc10681ef432010Johnny Chen addr_t address; // the PC relative address 1072788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen uint32_t data; // the literal data value from the PC relative load 1073788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen switch (encoding) { 1074788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen case eEncodingT1: 1075c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 10, 8); 1076788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1077c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = true; 1078c9de910d61f0471d18fced716fc10681ef432010Johnny Chen break; 1079c9de910d61f0471d18fced716fc10681ef432010Johnny Chen case eEncodingT2: 1080c9de910d61f0471d18fced716fc10681ef432010Johnny Chen Rt = Bits32(opcode, 15, 12); 1081c9de910d61f0471d18fced716fc10681ef432010Johnny Chen imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1082c9de910d61f0471d18fced716fc10681ef432010Johnny Chen add = BitIsSet(opcode, 23); 1083098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (Rt == 15 && InITBlock() && !LastInITBlock()) 1084c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1085788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen break; 1086788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen default: 1087788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return false; 1088788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1089c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1090e39f22d1a369866808b8739c3cec15063d806833Johnny Chen base = Align(pc, 4); 1091c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (add) 1092c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base + imm32; 1093c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 1094c9de910d61f0471d18fced716fc10681ef432010Johnny Chen address = base - imm32; 1095e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 1096e39f22d1a369866808b8739c3cec15063d806833Johnny Chen context.SetRegisterPlusOffset(pc_reg, address - base); 1097cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 1098788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen if (!success) 1099809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen return false; 1100c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1101c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Rt == 15) 1102c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1103c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (Bits32(address, 1, 0) == 0) 1104c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1105c9de910d61f0471d18fced716fc10681ef432010Johnny Chen // In ARMv5T and above, this is an interworking branch. 1106668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 1107c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1108c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1109c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else 1110c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1111c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1112c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1113c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 1114c9de910d61f0471d18fced716fc10681ef432010Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1115c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1116c9de910d61f0471d18fced716fc10681ef432010Johnny Chen } 1117c9de910d61f0471d18fced716fc10681ef432010Johnny Chen else // We don't handle ARM for now. 1118c9de910d61f0471d18fced716fc10681ef432010Johnny Chen return false; 1119c9de910d61f0471d18fced716fc10681ef432010Johnny Chen 1120788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen } 1121788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen return true; 1122788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen} 1123788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen 11245b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP. 1125fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate) 11262b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 11277bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1128fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{ 1129fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0 1130fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen // ARM pseudo code... 1131fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (ConditionPassed()) 1132fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 1133fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen EncodingSpecificOperations(); 1134bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1135fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if d == 15 then // Can only occur for ARM encoding 1136fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 1137fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen else 1138fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen R[d] = result; 1139fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if setflags then 1140fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.N = result<31>; 1141fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.Z = IsZeroBit(result); 1142fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.C = carry; 1143fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen APSR.V = overflow; 1144fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1145fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif 1146fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1147fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen bool success = false; 1148fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 11497bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1150fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen { 1151e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1152fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen if (!success) 1153fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return false; 1154fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen uint32_t imm32; // the immediate operand 1155e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice uint32_t d; 1156e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice bool setflags; 1157e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice switch (encoding) 1158e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1159e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice case eEncodingT1: 1160bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1161e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice d = Bits32 (opcode, 10, 8); 1162e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice setflags = false; 1163e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice imm32 = (Bits32 (opcode, 7, 0) << 2); 1164e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1165e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice break; 1166e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1167e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice case eEncodingT2: 1168bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1169e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice d = 13; 1170e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice setflags = false; 1171e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1172e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1173e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice break; 1174e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice 1175e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice default: 1176e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1177fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1178fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t sp_offset = imm32; 1179fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1180fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 11819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 11829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 11839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 1184fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1185e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (d == 15) 1186e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1187e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (!ALUWritePC (context, addr)) 1188e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1189e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice } 1190e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice else 1191e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 1192e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1193e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice return false; 1194e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice } 1195fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen } 1196fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen return true; 1197fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen} 1198fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen 1199fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP. 12005b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register) 12012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 12027bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 12035b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{ 12045b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0 12055b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen // ARM pseudo code... 12065b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (ConditionPassed()) 12075b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 12085b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen EncodingSpecificOperations(); 12095b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1210bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 12115b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if d == 15 then 12125b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen ALUWritePC(result); // setflags is always FALSE here 12135b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen else 12145b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen R[d] = result; 12155b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if setflags then 12165b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.N = result<31>; 12175b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.Z = IsZeroBit(result); 12185b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.C = carry; 12195b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen APSR.V = overflow; 12205b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 12215b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif 12225b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12235b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen bool success = false; 12245b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12257bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 12265b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen { 1227e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 12285b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 12295b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12305b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen uint32_t Rm; // the second operand 12315b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen switch (encoding) { 12325b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen case eEncodingT2: 12335b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen Rm = Bits32(opcode, 6, 3); 12345b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen break; 12355b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen default: 12365b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12375b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 1238e39f22d1a369866808b8739c3cec15063d806833Johnny Chen int32_t reg_value = ReadCoreReg(Rm, &success); 12395b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen if (!success) 12405b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12415b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12425b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 12435b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 12469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (reg_value); 12475b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 12495b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return false; 12505b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen } 12515b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen return true; 12525b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen} 12535b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen 12549b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 12559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or 12569b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM. 12579b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate) 12589b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 12597bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 12609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 12619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 12629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 12639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 12649b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 12659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 12669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 12679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC - 4; 12689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 12699b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = PC<31:1> : '1'; 12709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if targetInstrSet == InstrSet_ARM then 12719b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = Align(PC,4) + imm32; 12729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 12739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen targetAddress = PC + imm32; 12749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen SelectInstrSet(targetInstrSet); 12759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BranchWritePC(targetAddress); 12769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 12779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 12789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 12797bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = true; 12809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 12817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 12829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 12839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 12849bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1285e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 12869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 12879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 128853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t lr; // next instruction address 128953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 12909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen int32_t imm32; // PC-relative offset 12919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 1292d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen case eEncodingT1: 1293d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 1294e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1295bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 1296d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 1297bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1298bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 1299d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 1300d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I1 = !(J1 ^ S); 1301d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen uint32_t I2 = !(J2 ^ S); 130253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1303d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1304e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 13059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1306098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1307ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1308d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen break; 1309d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen } 13109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT2: 13119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 1312e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc | 1u; // return address 1313bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 13149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10H = Bits32(opcode, 25, 16); 1315bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 1316bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 13179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t imm10L = Bits32(opcode, 10, 1); 13189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I1 = !(J1 ^ S); 13199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t I2 = !(J2 ^ S); 132053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 13219b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 1322e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 13239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1324098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1325ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 13269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 13279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1328c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen case eEncodingA1: 13292b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice lr = pc - 4; // return address 1330c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1331e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = Align(pc, 4) + imm32; 13329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1333c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen break; 13349b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA2: 13352b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice lr = pc - 4; // return address 13369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1337e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 13389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 13399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 13409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 13419b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 13439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 13449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 13469b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 13489b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 13499b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 13509b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 13519b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and 13529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register. 13539b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register) 13549b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool 13557bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 13569b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{ 13579b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0 13589b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // ARM pseudo code... 13599b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (ConditionPassed()) 13609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 13619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen EncodingSpecificOperations(); 13629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen target = R[m]; 13639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if CurrentInstrSet() == InstrSet_ARM then 13649b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 4; 13659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen LR = next_instr_addr; 13669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen else 13679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen next_instr_addr = PC - 2; 1368bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice LR = next_instr_addr<31:1> : '1'; 13699b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen BXWritePC(target); 13709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 13719b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif 13729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 13739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen bool success = false; 13749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 13757bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 13769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 13779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 13789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1379e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 13809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen addr_t lr; // next instruction address 13819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!success) 13829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 13839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen uint32_t Rm; // the register with the target address 13849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen switch (encoding) { 13859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingT1: 1386e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = (pc - 2) | 1u; // return address 13879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 6, 3); 13889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 13899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 13909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1391098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1392ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 13939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen break; 13949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen case eEncodingA1: 1395e39f22d1a369866808b8739c3cec15063d806833Johnny Chen lr = pc - 4; // return address 13969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen Rm = Bits32(opcode, 3, 0); 13979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen // if m == 15 then UNPREDICTABLE; 13989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (Rm == 15) 13999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1400b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 14019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen default: 14029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 1404e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1405ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1406ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 14079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 14089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 14099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegister (dwarf_reg); 14109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 14119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 1412668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 14139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return false; 14149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen } 14159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen return true; 14169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen} 14179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen 1418ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1419ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool 14207bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1421ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{ 1422ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0 1423ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // ARM pseudo code... 1424ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (ConditionPassed()) 1425ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 1426ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen EncodingSpecificOperations(); 1427ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen BXWritePC(R[m]); 1428ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1429ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif 1430ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 14317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1432ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 14339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 14349bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1435ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen uint32_t Rm; // the register with the target address 1436ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen switch (encoding) { 1437ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingT1: 1438ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 6, 3); 1439098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (InITBlock() && !LastInITBlock()) 1440ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1441ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1442ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen case eEncodingA1: 1443ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen Rm = Bits32(opcode, 3, 0); 1444ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen break; 1445ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen default: 1446ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1447ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 14487bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1449e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 1450ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen if (!success) 1451ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 14529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 14539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 14549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1455668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetRegister (dwarf_reg); 1456668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!BXWritePC(context, target)) 1457ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return false; 1458ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen } 1459ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen return true; 1460ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen} 1461ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen 146259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 146359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// address and instruction set specified by a register as though it were a BX instruction. 146459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// 146559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// TODO: Emulate Jazelle architecture? 146659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 146759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chenbool 14687bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 146959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen{ 147059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#if 0 147159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // ARM pseudo code... 147259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (ConditionPassed()) 147359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 147459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen EncodingSpecificOperations(); 1475bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 147659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen BXWritePC(R[m]); 147759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen else 147859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if JazelleAcceptsExecution() then 147959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen SwitchToJazelleExecution(); 148059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen else 148159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen SUBARCHITECTURE_DEFINED handler call; 148259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 148359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#endif 148459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 14857bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 148659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 148759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen EmulateInstruction::Context context; 148859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 148959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen uint32_t Rm; // the register with the target address 149059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen switch (encoding) { 149159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen case eEncodingT1: 149259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Rm = Bits32(opcode, 19, 16); 149359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (BadReg(Rm)) 149459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 149559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (InITBlock() && !LastInITBlock()) 149659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 149759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen break; 149859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen case eEncodingA1: 149959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Rm = Bits32(opcode, 3, 0); 150059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (Rm == 15) 150159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 150259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen break; 150359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen default: 150459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 150559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 15067bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 150759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen addr_t target = ReadCoreReg (Rm, &success); 150859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (!success) 150959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 151059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 151159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen Register dwarf_reg; 151259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 151359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen context.SetRegister (dwarf_reg); 151459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen if (!BXWritePC(context, target)) 151559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return false; 151659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen } 151759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen return true; 151859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen} 151959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen 15200d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset. 15210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate) 15222b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 15237bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 15240d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 15250d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 15260d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 15270d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 15280d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15290d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 1530bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 15310d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 15320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 15330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 15340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 15350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 15360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 15370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 15380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 15390d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 15400d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15410d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 15420d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15437bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 15440d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15457bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1546e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t ip = ReadCoreReg (12, &success); 15470d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 15480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 15490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 15500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 15510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 15520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 15530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 15540d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 15550d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 15560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t ip_offset = imm32; 15580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = ip - ip_offset; // the adjusted ip value 15590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 15619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 15629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 15639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 15649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 15650d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15662b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 15670d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 15680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 15700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 15710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset. 15730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate) 15742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 15757bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 15760d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{ 15770d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0 15780d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen // ARM pseudo code... 15790d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (ConditionPassed()) 15800d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15810d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen EncodingSpecificOperations(); 1582bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 15830d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if d == 15 then // Can only occur for ARM encoding 15840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 15850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen else 15860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen R[d] = result; 15870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if setflags then 15880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.N = result<31>; 15890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.Z = IsZeroBit(result); 15900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.C = carry; 15910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen APSR.V = overflow; 15920d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 15930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif 15940d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 15957bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 15960d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen { 15977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton bool success = false; 1598e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 15990d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen if (!success) 16000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen uint32_t imm32; 16020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen switch (encoding) { 16030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen case eEncodingA1: 16040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 16050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen break; 16060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen default: 16070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16080d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 16090d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t sp_offset = imm32; 16100d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen addr_t addr = sp - sp_offset; // the adjusted stack pointer value 16110d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 16129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 16139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 16149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 16159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 16169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 16170d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 16182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 16190d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return false; 16200d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen } 16210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen return true; 16220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen} 16230d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen 1624c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// This instruction subtracts an immediate value from the SP value, and writes 1625c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// the result to the destination register. 1626c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// 1627c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 16282b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 16297bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 16304c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{ 16314c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0 16324c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen // ARM pseudo code... 16334c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (ConditionPassed()) 16344c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 16354c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen EncodingSpecificOperations(); 1636bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 163715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if d == 15 then // Can only occur for ARM encoding 1638799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen ALUWritePC(result); // setflags is always FALSE here 16394c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen else 16404c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen R[d] = result; 16414c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if setflags then 16424c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.N = result<31>; 16434c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.Z = IsZeroBit(result); 16444c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.C = carry; 16454c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen APSR.V = overflow; 16464c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 16474c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif 16484c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 16494c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen bool success = false; 16507bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 16514c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen { 1652e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 16534c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen if (!success) 16544c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 1655c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 1656c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen uint32_t Rd; 1657c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen bool setflags; 16584c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen uint32_t imm32; 16594c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen switch (encoding) { 1660e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen case eEncodingT1: 1661c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = 13; 1662c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = false; 1663a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1664ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 166560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT2: 1666c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 11, 8); 1667c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = BitIsSet(opcode, 20); 166860c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1669c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 15 && setflags) 16707bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateCMPImm(opcode, eEncodingT2); 1671c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 15 && !setflags) 1672c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen return false; 167360c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 167460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen case eEncodingT3: 1675c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 11, 8); 1676c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = false; 167760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 167815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15) 167915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 168060c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen break; 16814c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen case eEncodingA1: 1682c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen Rd = Bits32(opcode, 15, 12); 1683c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen setflags = BitIsSet(opcode, 20); 168460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 168515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 168615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 168715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 168815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 16894c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen break; 16904c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen default: 16914c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 16924c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 1693c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1694c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 16959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 1696c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (Rd == 13) 1697c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 16982b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 16992b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice // value gets passed down to context.SetImmediateSigned. 1700c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 17012b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice context.SetImmediateSigned (-imm64); // the stack pointer offset 1702c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen } 1703c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen else 1704c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 1705c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.type = EmulateInstruction::eContextImmediate; 1706c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen context.SetNoArgs (); 1707c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen } 1708c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen 1709c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 17104c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return false; 17114c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen } 17124c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen return true; 17134c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen} 17144c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen 171508c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP. 17162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 17177bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1718ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{ 1719ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0 1720ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen // ARM pseudo code... 1721ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (ConditionPassed()) 1722ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1723ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen EncodingSpecificOperations(); 1724ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1725ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen address = if index then offset_addr else R[n]; 1726ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1727ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if wback then R[n] = offset_addr; 1728ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1729ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif 1730ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 1731ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen bool success = false; 1732ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 17337bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1734ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 17352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1736e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1737ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1738ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 173991d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen uint32_t Rt; // the source register 1740ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen uint32_t imm12; 17413e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 17423e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17433e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool index; 17443e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool add; 17453e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice bool wback; 1746ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen switch (encoding) { 1747ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen case eEncodingA1: 1748108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen Rt = Bits32(opcode, 15, 12); 1749108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen imm12 = Bits32(opcode, 11, 0); 17503e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice Rn = Bits32 (opcode, 19, 16); 17513e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17523e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 17533e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 17543e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17553e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice index = BitIsSet (opcode, 24); 17563e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice add = BitIsSet (opcode, 23); 17573e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 17583e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17593e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (wback && ((Rn == 15) || (Rn == Rt))) 17603e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 1761ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen break; 1762ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen default: 1763ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1764ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 17653e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr_t offset_addr; 17663e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (add) 17673e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice offset_addr = sp + imm12; 17683e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice else 17693e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice offset_addr = sp - imm12; 17703e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 17713e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr_t addr; 17723e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (index) 17733e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr = offset_addr; 17743e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice else 17753e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice addr = sp; 1776ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 17779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 17789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 17793e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice Register sp_reg; 17803e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 17813e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 178291d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen if (Rt != 15) 1783ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1784e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_value = ReadCoreReg(Rt, &success); 1785ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1786ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1787cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1788ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1789ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1790ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen else 1791ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen { 1792e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 1793ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen if (!success) 1794ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 17958d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemUWrite (context, addr, pc, addr_byte_size)) 1796ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return false; 1797ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1798ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 17993e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice 18003e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (wback) 18013e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice { 18023e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.type = EmulateInstruction::eContextAdjustStackPointer; 18033e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice context.SetImmediateSigned (addr - sp); 18043e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 18053e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice return false; 18063e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice } 1807ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen } 1808ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen return true; 1809ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen} 1810ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen 181108c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack. 181208c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data. 18132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool 18147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1815799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{ 1816799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0 1817799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // ARM pseudo code... 1818799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (ConditionPassed()) 1819799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 1820799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1821799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = SP - imm32; 1822799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen SP = SP - imm32; 1823799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if single_regs then 1824799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1825799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = S[d+r]; address = address+4; 1826799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen else 1827799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen for r = 0 to regs-1 1828799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // Store as two word-aligned words in the correct order for current endianness. 1829799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1830799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1831799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen address = address+8; 1832799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1833799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif 1834799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1835799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool success = false; 1836799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 18377bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1838799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 18392b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const uint32_t addr_byte_size = GetAddressByteSize(); 1840e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1841799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1842799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1843799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen bool single_regs; 1844587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1845799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t imm32; // stack offset 1846799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t regs; // number of registers 1847799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen switch (encoding) { 1848799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT1: 1849799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA1: 1850799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = false; 1851bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1852799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1853799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // If UInt(imm8) is odd, see "FSTMX". 1854799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 1855799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1856799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1857799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1858799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 1859799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingT2: 1860799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen case eEncodingA2: 1861799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen single_regs = true; 1862bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1863799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1864799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen regs = Bits32(opcode, 7, 0); 1865799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1866799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1867799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1868799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen break; 1869799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen default: 1870799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1871799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1872799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1873799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1874799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t sp_offset = imm32; 1875799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr_t addr = sp - sp_offset; 1876799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen uint32_t i; 1877799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 18789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 18799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPushRegisterOnStack; 18809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 18819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1882bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice Register sp_reg; 1883bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 1884bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice for (i=0; i<regs; ++i) 1885799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen { 1886bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice dwarf_reg.num = start_reg + d + i; 1887bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1888799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen // uint64_t to accommodate 64-bit registers. 18899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1890799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen if (!success) 1891799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1892cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 1893799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1894799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen addr += reg_byte_size; 1895799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1896799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1897799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 18989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (-sp_offset); 1899799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 19002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1901799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return false; 1902799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen } 1903799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen return true; 1904799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen} 1905799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen 1906587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack. 1907587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data. 1908587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool 19097bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 1910587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{ 1911587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0 1912587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // ARM pseudo code... 1913587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (ConditionPassed()) 1914587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1915587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1916587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen address = SP; 1917587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen SP = SP + imm32; 1918587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if single_regs then 1919587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 1920587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen S[d+r] = MemA[address,4]; address = address+4; 1921587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen else 1922587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen for r = 0 to regs-1 1923587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1924587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Combine the word-aligned words in the correct order for current endianness. 1925587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1926587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1927587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif 1928587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1929587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool success = false; 1930587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 19317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 1932587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1933587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen const uint32_t addr_byte_size = GetAddressByteSize(); 1934e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const addr_t sp = ReadCoreReg (SP_REG, &success); 1935587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1936587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1937587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen bool single_regs; 1938587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1939587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t imm32; // stack offset 1940587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t regs; // number of registers 1941587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen switch (encoding) { 1942587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT1: 1943587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA1: 1944587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = false; 1945bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1946587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1947587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // If UInt(imm8) is odd, see "FLDMX". 1948587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0) / 2; 1949587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1950587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1951587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1952587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 1953587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingT2: 1954587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen case eEncodingA2: 1955587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen single_regs = true; 1956bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1957587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1958587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen regs = Bits32(opcode, 7, 0); 1959587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1960587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (regs == 0 || regs > 16 || (d + regs) > 32) 1961587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1962587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen break; 1963587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen default: 1964587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1965587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1966587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1967587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1968587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t sp_offset = imm32; 1969587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr_t addr = sp; 1970587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint32_t i; 1971587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen uint64_t data; // uint64_t to accomodate 64-bit registers. 1972587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 19739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 19749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 19759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 19769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1977bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice Register sp_reg; 1978bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 1979bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice for (i=0; i<regs; ++i) 1980587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen { 1981bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice dwarf_reg.num = start_reg + d + i; 1982bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (sp_reg, addr - sp); 1983cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemARead(context, addr, reg_byte_size, 0, &success); 1984587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!success) 1985587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 19869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1987587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1988587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen addr += reg_byte_size; 1989587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1990587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1991587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen context.type = EmulateInstruction::eContextAdjustStackPointer; 19929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (sp_offset); 1993587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 1994587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1995587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return false; 1996587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen } 1997587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen return true; 1998587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen} 1999587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen 2000b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI) 2001b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool 20027bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2003b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{ 2004b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0 2005b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // ARM pseudo code... 2006b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (ConditionPassed()) 2007b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 2008b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen EncodingSpecificOperations(); 2009b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen CallSupervisor(); 2010b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 2011b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif 2012b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 2013b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen bool success = false; 2014b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 20157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 2016b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 2017e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 2018b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen addr_t lr; // next instruction address 2019b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!success) 2020b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2021b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t imm32; // the immediate constant 2022b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen uint32_t mode; // ARM or Thumb mode 2023b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen switch (encoding) { 2024b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingT1: 2025b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = (pc + 2) | 1u; // return address 2026b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 7, 0); 2027b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeThumb; 2028b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 2029b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen case eEncodingA1: 2030b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen lr = pc + 4; // return address 2031b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen imm32 = Bits32(opcode, 23, 0); 2032b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen mode = eModeARM; 2033b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen break; 2034b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen default: 2035b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2036b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 20379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 20389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 20399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextSupervisorCall; 20409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediate (mode, imm32); 2041b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2042b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return false; 2043b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen } 2044b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen return true; 2045b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen} 2046b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 2047c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional. 2048c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool 20497bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2050c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{ 2051c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0 2052c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // ARM pseudo code... 2053c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen EncodingSpecificOperations(); 2054c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen ITSTATE.IT<7:0> = firstcond:mask; 2055c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif 2056c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 2057c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.InitIT(Bits32(opcode, 7, 0)); 2058c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen return true; 2059c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen} 2060c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 20613b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address. 20623b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool 20637bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 20643b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{ 20653b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0 20663b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // ARM pseudo code... 20673b620b38cd170c20ea607585021ab2ab50286943Johnny Chen if (ConditionPassed()) 20683b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 20693b620b38cd170c20ea607585021ab2ab50286943Johnny Chen EncodingSpecificOperations(); 20703b620b38cd170c20ea607585021ab2ab50286943Johnny Chen BranchWritePC(PC + imm32); 20713b620b38cd170c20ea607585021ab2ab50286943Johnny Chen } 20723b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif 20733b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 20743b620b38cd170c20ea607585021ab2ab50286943Johnny Chen bool success = false; 20753b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 20767bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 20779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 20789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 20799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2080e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 20819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!success) 20829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 208353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 20849ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen int32_t imm32; // PC-relative offset 20859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen switch (encoding) { 20869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT1: 20879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 20889ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2089e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 20909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 20919ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 20929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT2: 20939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2094e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 20959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 20969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 20979ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT3: 20989ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 20999ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 2100bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 21019ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm6 = Bits32(opcode, 21, 16); 2102bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 2103bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 21049ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 210553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 21069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<21>(imm21); 2107e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 21099ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 21109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21119ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingT4: 21129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 2113bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t S = Bit32(opcode, 26); 21149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm10 = Bits32(opcode, 25, 16); 2115bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J1 = Bit32(opcode, 13); 2116bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen uint32_t J2 = Bit32(opcode, 11); 21179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t imm11 = Bits32(opcode, 10, 0); 21189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I1 = !(J1 ^ S); 21199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen uint32_t I2 = !(J2 ^ S); 212053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 21219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<25>(imm25); 2122e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 21249ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 21259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eEncodingA1: 21279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2128e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 21309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 21319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 21329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 21339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21349ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!BranchWritePC(context, target)) 21359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; 21369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 21379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return true; 21383b620b38cd170c20ea607585021ab2ab50286943Johnny Chen} 21393b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 214053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 214153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value. They do not affect the condition flags. 214253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ 214353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool 21447bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 214553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{ 214653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0 214753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // ARM pseudo code... 214853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen EncodingSpecificOperations(); 214953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if nonzero ^ IsZero(R[n]) then 215053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen BranchWritePC(PC + imm32); 215153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif 215253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 215353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool success = false; 215453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 215553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // Read the register value from the operand register Rn. 2156e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 215753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 215853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 215953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 21609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 21619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2162e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 216353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!success) 216453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 216553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 216653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen addr_t target; // target address 216753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen uint32_t imm32; // PC-relative offset to branch forward 216853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen bool nonzero; 216953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen switch (encoding) { 217053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen case eEncodingT1: 2171bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 217253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen nonzero = BitIsSet(opcode, 11); 2173e39f22d1a369866808b8739c3cec15063d806833Johnny Chen target = pc + imm32; 21749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 217553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen break; 217653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen default: 217753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 217853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen } 217953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (nonzero ^ (reg_val == 0)) 218053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen if (!BranchWritePC(context, target)) 218153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 218253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 218353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 218453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen} 218553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 218660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 218760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 218860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table. 218960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// 219060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 219160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table. 219260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table. 219360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH 219460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool 21957bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 219660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{ 219760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0 219860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // ARM pseudo code... 219960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(n); 220060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if is_tbh then 220160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 220260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen else 220360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen halfwords = UInt(MemU[R[n]+R[m], 1]); 220460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen BranchWritePC(PC + 2*halfwords); 220560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif 220660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 220760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool success = false; 220860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 220960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rn; // the base register which contains the address of the table of branch lengths 221060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 221160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen bool is_tbh; // true if table branch halfword 221260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen switch (encoding) { 221360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen case eEncodingT1: 221460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rn = Bits32(opcode, 19, 16); 221560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen Rm = Bits32(opcode, 3, 0); 221660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen is_tbh = BitIsSet(opcode, 4); 221760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (Rn == 13 || BadReg(Rm)) 221860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 221960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (InITBlock() && !LastInITBlock()) 222060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 222160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen break; 222260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen default: 222360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 222460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen } 222560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 222660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // Read the address of the table from the operand register Rn. 222760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // The PC can be used, in which case the table immediately follows this instruction. 2228e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t base = ReadCoreReg(Rm, &success); 222960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 223060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 223160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 223260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the table index 2233e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t index = ReadCoreReg(Rm, &success); 223460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 223560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 223660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 223760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // the offsetted table address 223860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen addr_t addr = base + (is_tbh ? index*2 : index); 223960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 224060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // PC-relative offset to branch forward 224160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen EmulateInstruction::Context context; 224260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextTableBranchReadMemory; 2243104c8b69863f229033d616245f56243ca51f1de9Johnny Chen uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 224460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 224560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 224660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 2247e39f22d1a369866808b8739c3cec15063d806833Johnny Chen const uint32_t pc = ReadCoreReg(PC_REG, &success); 224860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!success) 224960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 225060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 225160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // target address 2252e39f22d1a369866808b8739c3cec15063d806833Johnny Chen addr_t target = pc + offset; 225360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.type = EmulateInstruction::eContextRelativeBranchImmediate; 225460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen context.SetModeAndImmediateSigned (eModeThumb, 4 + offset); 225560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 225660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen if (!BranchWritePC(context, target)) 225760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return false; 225860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 225960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen return true; 226060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen} 226160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen 2262dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// This instruction adds an immediate value to a register value, and writes the result to the destination register. 2263dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// It can optionally update the condition flags based on the result. 2264dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Ticebool 22657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2266dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice{ 2267dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#if 0 2268dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if ConditionPassed() then 2269dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice EncodingSpecificOperations(); 2270bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2271dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice R[d] = result; 2272dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if setflags then 2273dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.N = result<31>; 2274dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.Z = IsZeroBit(result); 2275dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.C = carry; 2276dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice APSR.V = overflow; 2277dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#endif 2278dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2279dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice bool success = false; 2280dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 22817bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 2282dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2283dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t d; 2284dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t n; 2285dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice bool setflags; 2286dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm32; 2287dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t carry_out; 2288dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2289dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //EncodingSpecificOperations(); 2290dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice switch (encoding) 2291dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2292dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT1: 2293dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2294dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 2, 0); 2295dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 5, 3); 2296dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = !InITBlock(); 2297dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = Bits32 (opcode, 8,6); 2298dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2299dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2300dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2301dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT2: 2302dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2303dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 10, 8); 2304dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 10, 8); 2305dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = !InITBlock(); 2306dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = Bits32 (opcode, 7, 0); 2307dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2308dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2309dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2310dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT3: 2311bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2312bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE ADD (SP plus immediate); 2313bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2314dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 11, 8); 2315dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 19, 16); 2316dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = BitIsSet (opcode, 20); 2317dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2318dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2319dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // if BadReg(d) || n == 15 then UNPREDICTABLE; 2320dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (BadReg (d) || (n == 15)) 2321dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2322dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2323dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2324dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2325dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice case eEncodingT4: 2326dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 2327bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE ADR; 2328bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE ADD (SP plus immediate); 2329dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2330dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice d = Bits32 (opcode, 11, 8); 2331dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice n = Bits32 (opcode, 19, 16); 2332dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice setflags = false; 2333dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t i = Bit32 (opcode, 26); 2334dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm3 = Bits32 (opcode, 14, 12); 2335dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint32_t imm8 = Bits32 (opcode, 7, 0); 2336dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice imm32 = (i << 11) | (imm3 << 8) | imm8; 2337dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2338dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // if BadReg(d) then UNPREDICTABLE; 2339dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (BadReg (d)) 2340dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2341dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2342dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice break; 2343dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2344dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice default: 2345dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2346dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2347dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2348dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2349dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (!success) 2350dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2351dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2352bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2353dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2354dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2355dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice Register reg_n; 2356dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2357dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2358dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice EmulateInstruction::Context context; 2359dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice context.type = eContextAddition; 2360dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice context.SetRegisterPlusOffset (reg_n, imm32); 2361dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2362dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //R[d] = result; 2363dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //if setflags then 2364dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.N = result<31>; 2365dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.Z = IsZeroBit(result); 2366dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.C = carry; 2367dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice //APSR.V = overflow; 2368dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2369dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return false; 2370dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 2371dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice } 2372dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice return true; 2373dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice} 2374dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice 23758fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// This instruction adds an immediate value to a register value, and writes the result to the destination 23768fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// register. It can optionally update the condition flags based on the result. 23778fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chenbool 23787bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 23798fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen{ 23808fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#if 0 23818fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // ARM pseudo code... 23828fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if ConditionPassed() then 23838fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EncodingSpecificOperations(); 23848fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 23858fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if d == 15 then 23868fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen ALUWritePC(result); // setflags is always FALSE here 23878fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen else 23888fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen R[d] = result; 23898fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if setflags then 23908fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.N = result<31>; 23918fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.Z = IsZeroBit(result); 23928fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.C = carry; 23938fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen APSR.V = overflow; 23948fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#endif 23958fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 23968fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool success = false; 23978fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 23987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 23998fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 24008fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t Rd, Rn; 24018fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 24028fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen bool setflags; 24038fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen switch (encoding) 24048fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen { 24058fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 24068fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 24078fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 24088fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 24098fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 24108fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 24118fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen default: 24128fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 24138fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 24148fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24158fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // Read the first operand. 2416157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 24178fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!success) 24188fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 24198fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24208fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 24218fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24228fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen EmulateInstruction::Context context; 24238fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen context.type = EmulateInstruction::eContextImmediate; 24248fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen context.SetNoArgs (); 24258fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 24268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 24278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return false; 24288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen } 24298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen return true; 24308fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen} 24318fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen 2432d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result 2433d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 243426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 24357bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 243626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 243726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0 243826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // ARM pseudo code... 243926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if ConditionPassed() then 244026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen EncodingSpecificOperations(); 244126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 244226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 244326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if d == 15 then 244426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen ALUWritePC(result); // setflags is always FALSE here 244526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 244626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen R[d] = result; 244726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if setflags then 244826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.N = result<31>; 244926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.Z = IsZeroBit(result); 245026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.C = carry; 245126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen APSR.V = overflow; 245226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif 245326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 245426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen bool success = false; 245526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 24567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 245726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 245826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen uint32_t Rd, Rn, Rm; 2459d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen ARM_ShifterType shift_t; 2460d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2461ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen bool setflags; 246226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen switch (encoding) 246326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen { 2464d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen case eEncodingT1: 2465d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rd = Bits32(opcode, 2, 0); 2466d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rn = Bits32(opcode, 5, 3); 2467d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen Rm = Bits32(opcode, 8, 6); 2468d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen setflags = !InITBlock(); 2469d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2470d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 2471ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 247226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen case eEncodingT2: 2473bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 247426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen Rm = Bits32(opcode, 6, 3); 2475ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen setflags = false; 2476d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_t = SRType_LSL; 2477d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen shift_n = 0; 247826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (Rn == 15 && Rm == 15) 247926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 2480d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen if (Rd == 15 && InITBlock() && !LastInITBlock()) 2481d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen return false; 248226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen break; 24838fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen case eEncodingA1: 24848fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rd = Bits32(opcode, 15, 12); 24858fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rn = Bits32(opcode, 19, 16); 24868fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen Rm = Bits32(opcode, 3, 0); 24878fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen setflags = BitIsSet(opcode, 20); 24883dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 24898fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen break; 249026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen default: 249126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 249226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 249326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 249426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the first operand. 2495157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 249626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 249726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 249826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 249926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Read the second operand. 2500157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 250126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (!success) 250226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return false; 250326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 2504e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 25058fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 25069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 25079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 25088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = EmulateInstruction::eContextAddition; 25098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register op1_reg; 25108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register op2_reg; 25118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 25128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 25138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2514ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 251510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2516ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 251726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen } 251826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return true; 251926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 252026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 252134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (immediate) adds a register value and an immediate value. 252234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 252334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 25247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 252534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 252634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 252734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 252834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 252934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 253034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 253134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 253234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 253334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 253434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 253534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 253634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 253734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 253834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 253934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 254034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t imm32; // the immediate value to be compared with 254134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 254234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 2543078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2544078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2545078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15) 2546078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen return false; 2547ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 254834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 254934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 255034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 255134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 255234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 255334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 255434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 255534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from the operand register Rn. 255634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 255734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 255834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 255934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2560078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 256134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 256234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 256334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 256434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs (); 256534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 256634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 256734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 256834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 256934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 257034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 257134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (register) adds a register value and an optionally-shifted register value. 257234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 257334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool 25747bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 257534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{ 257634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0 257734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // ARM pseudo code... 257834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if ConditionPassed() then 257934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EncodingSpecificOperations(); 258034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 258134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 258234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.N = result<31>; 258334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.Z = IsZeroBit(result); 258434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.C = carry; 258534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen APSR.V = overflow; 258634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif 258734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 258834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen bool success = false; 258934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 259034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rn; // the first operand 259134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t Rm; // the second operand 259234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 259334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 259434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen switch (encoding) { 259534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT1: 259634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 2, 0); 259734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 5, 3); 259834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 259934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 260034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 260134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingT2: 2602078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2603078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rm = Bits32(opcode, 3, 0); 26043dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 2605078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen // if n == 15 || BadReg(m) then UNPREDICTABLE; 2606078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15 || BadReg(Rm)) 260734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 260834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen break; 260934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 261034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 261134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 26123dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 2613ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 261434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen default: 261534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 261634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen } 261734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rn. 261834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 261934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 262034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 262134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 262234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // Read the register value from register Rm. 262334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 262434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!success) 262534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 262634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 262734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 2628078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 262934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 263034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen EmulateInstruction::Context context; 263134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.type = EmulateInstruction::eContextImmediate; 263234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen context.SetNoArgs(); 263334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 263434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return false; 263534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 263634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen return true; 263734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen} 263834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 263934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (immediate) subtracts an immediate value from a register value. 264034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2641d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool 26427bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2643d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{ 2644d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0 2645d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // ARM pseudo code... 2646d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if ConditionPassed() then 2647d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen EncodingSpecificOperations(); 2648d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2649d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.N = result<31>; 2650d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.Z = IsZeroBit(result); 2651d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.C = carry; 2652d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen APSR.V = overflow; 2653d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif 2654d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2655d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen bool success = false; 2656d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 2657d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t Rn; // the first operand 2658d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen uint32_t imm32; // the immediate value to be compared with 2659d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen switch (encoding) { 2660d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen case eEncodingT1: 2661d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen Rn = Bits32(opcode, 10, 8); 2662d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen imm32 = Bits32(opcode, 7, 0); 2663ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 2664078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen case eEncodingT2: 2665078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen Rn = Bits32(opcode, 19, 16); 2666078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2667078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen if (Rn == 15) 2668078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen return false; 2669ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 267034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 267134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 267234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2673d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen break; 2674d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen default: 2675d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2676d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen } 2677d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen // Read the register value from the operand register Rn. 2678e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 2679d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen if (!success) 2680d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return false; 2681d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 268210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 268310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 26849bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 26859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 26869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs (); 268710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 268810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 268910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2690d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen return true; 2691d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen} 2692d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen 269334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (register) subtracts an optionally-shifted register value from a register value. 269434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result. 2695e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool 26967bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2697e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{ 2698e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0 2699e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // ARM pseudo code... 2700e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if ConditionPassed() then 2701e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen EncodingSpecificOperations(); 2702e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2703e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2704e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.N = result<31>; 2705e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.Z = IsZeroBit(result); 2706e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.C = carry; 2707e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen APSR.V = overflow; 2708e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif 2709e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2710e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen bool success = false; 2711e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 2712e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rn; // the first operand 2713e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen uint32_t Rm; // the second operand 271434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen ARM_ShifterType shift_t; 271534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 2716e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen switch (encoding) { 2717e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT1: 2718e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bits32(opcode, 2, 0); 2719e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 5, 3); 272034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 272134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2722e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 2723e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen case eEncodingT2: 2724e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2725e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen Rm = Bits32(opcode, 6, 3); 272634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_t = SRType_LSL; 272734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen shift_n = 0; 2728e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn < 8 && Rm < 8) 2729e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2730e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (Rn == 15 || Rm == 15) 2731e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2732e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen break; 273334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen case eEncodingA1: 273434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rn = Bits32(opcode, 19, 16); 273534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen Rm = Bits32(opcode, 3, 0); 27363dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 2737ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 2738e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen default: 2739e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2740e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen } 2741e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rn. 274234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 2743e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2744e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 274534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen 2746e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen // Read the register value from register Rm. 274734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 2748e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen if (!success) 2749e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return false; 2750e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 275134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 275234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 275310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 27549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 27559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextImmediate; 27569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetNoArgs(); 275710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 275810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 275910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 2760e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen return true; 2761e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen} 2762e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen 276382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 276482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. It can 276582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result. 276682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool 27677bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 276882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{ 276982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0 277082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // ARM pseudo code... 277182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if ConditionPassed() then 277282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EncodingSpecificOperations(); 277382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 277482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if d == 15 then // Can only occur for ARM encoding 277582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 277682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen else 277782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen R[d] = result; 277882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if setflags then 277982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.N = result<31>; 278082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.Z = IsZeroBit(result); 278182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen APSR.C = carry; 278282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // APSR.V unchanged 278382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif 278482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 27857bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_ASR); 278641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 278741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 278841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 278941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register. 279041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update 279141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result. 279241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 27937bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 279441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 279541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 279641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 279741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 279841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 279941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 280041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 280141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 280241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 280341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 280441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 280541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 280641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 280741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 280841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_ASR); 281041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 281141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 281241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 281341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 281441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 281541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28167bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 281741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 281841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 281941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 282041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 282141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 282241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 282341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 282441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 282541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 282641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 282741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 282841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 282941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 283041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 283141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 283241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 283341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28347bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_LSL); 283541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 283641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 283741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits, 283841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 283941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 284041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 284141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28427bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 284341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 284441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 284541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 284641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 284741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 284841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 284941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 285041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 285141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 285241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 285341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 285441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 285541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 285641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 285741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28587bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_LSL); 285941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 286041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 286141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 286241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. It can optionally 286341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result. 286441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 286641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 286741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 286841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 286941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 287041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 287141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 287241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if d == 15 then // Can only occur for ARM encoding 287341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen ALUWritePC(result); // setflags is always FALSE here 287441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen else 287541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 287641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 287741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 287841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 287941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 288041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 288141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 288241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 28837bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_LSR); 288441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 288541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 288641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits, 288741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register. The variable number 288841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition 288941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result. 289041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 28917bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 289241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 289341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0 289441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // ARM pseudo code... 289541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if ConditionPassed() then 289641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen EncodingSpecificOperations(); 289741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen shift_n = UInt(R[m]<7:0>); 289841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 289941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen R[d] = result; 290041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen if setflags then 290141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.N = result<31>; 290241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.Z = IsZeroBit(result); 290341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen APSR.C = carry; 290441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen // APSR.V unchanged 290541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif 290641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 29077bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_LSR); 290841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen} 290941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 2910eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 2911eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2912eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result. 2913eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 29147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 2915eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2916eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2917eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2918eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2919eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2920eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2921eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 2922eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 2923eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 2924eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2925eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2926eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2927eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2928eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2929eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2930eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2931eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 29327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_ROR); 2933eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2934eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2935eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 2936eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2937eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 2938eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result. 2939eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 29407bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 2941eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2942eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2943eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2944eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2945eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2946eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_n = UInt(R[m]<7:0>); 2947eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2948eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2949eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2950eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2951eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2952eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2953eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2954eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2955eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 29567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftReg (opcode, encoding, SRType_ROR); 2957eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2958eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 2959eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 2960eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31]. 2961eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// 2962eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result. 2963eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag. 2964eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool 29657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 2966eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{ 2967eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0 2968eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ARM pseudo code... 2969eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if ConditionPassed() then 2970eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen EncodingSpecificOperations(); 2971eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 2972eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if d == 15 then // Can only occur for ARM encoding 2973eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen ALUWritePC(result); // setflags is always FALSE here 2974eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen else 2975eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen R[d] = result; 2976eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if setflags then 2977eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.N = result<31>; 2978eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.Z = IsZeroBit(result); 2979eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen APSR.C = carry; 2980eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // APSR.V unchanged 2981eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif 2982eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 29837bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateShiftImm (opcode, encoding, SRType_RRX); 2984eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen} 2985eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 298641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool 29877bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 298841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{ 2989bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice assert(shift_type == SRType_ASR 2990bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_LSL 2991bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_LSR 2992bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_ROR 2993bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || shift_type == SRType_RRX); 299441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen 299582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool success = false; 299682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 29977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 299882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 2999e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 3000e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the first operand register 3001e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t imm5; // encoding for the shift amount 300282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen uint32_t carry; // the carry bit after the shift operation 300382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen bool setflags; 3004eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 3005eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Special case handling! 3006eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) -- Encoding T1 30077bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton ARMEncoding use_encoding = encoding; 30087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3009eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 3010eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3011eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // have the same decoding of bit fields as the other Thumb2 shift operations. 30127bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton use_encoding = eEncodingT2; 3013eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen } 3014eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 30157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton switch (use_encoding) { 301682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT1: 3017eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Due to the above special case handling! 3018eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen assert(shift_type != SRType_ROR); 3019eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 302082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 2, 0); 302182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 5, 3); 302282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = !InITBlock(); 302382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 10, 6); 302482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 302582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingT2: 3026eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.141 RRX 3027eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen assert(shift_type != SRType_RRX); 3028eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 302982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 11, 8); 303082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 303182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 303282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 303382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (BadReg(Rd) || BadReg(Rm)) 303482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 303582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 303682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen case eEncodingA1: 303782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rd = Bits32(opcode, 15, 12); 303882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen Rm = Bits32(opcode, 3, 0); 303982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen setflags = BitIsSet(opcode, 20); 304082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen imm5 = Bits32(opcode, 11, 7); 304182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen break; 304282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen default: 304382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 304482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 304582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3046eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // A8.6.139 ROR (immediate) 3047eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen if (shift_type == SRType_ROR && imm5 == 0) 3048eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen shift_type = SRType_RRX; 3049eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen 305082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // Get the first operand. 3051e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rm, &success); 305282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen if (!success) 305382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return false; 305482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3055eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // Decode the shift amount if not RRX. 3056eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 305782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3058e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 305982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 306082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // The context specifies that an immediate is to be moved into Rd. 306182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen EmulateInstruction::Context context; 306282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 306382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen context.SetNoArgs (); 306482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 306510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3066ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 306782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen } 306882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen return true; 306982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen} 307082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen 3071e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool 30727bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3073e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{ 307441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 3075e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3076e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool success = false; 3077e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 30787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3079e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 3080e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rd; // the destination register 3081e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rn; // the first operand register 3082e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3083e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t carry; // the carry bit after the shift operation 3084e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen bool setflags; 3085e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen switch (encoding) { 3086e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT1: 3087e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 2, 0); 3088e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Rd; 3089e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 5, 3); 3090e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = !InITBlock(); 3091e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3092e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingT2: 3093e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 11, 8); 3094e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 19, 16); 3095e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 3, 0); 3096e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 3097e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3098e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3099e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3100e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen case eEncodingA1: 3101e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rd = Bits32(opcode, 15, 12); 3102e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rn = Bits32(opcode, 3, 0); 3103e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen Rm = Bits32(opcode, 11, 8); 3104e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen setflags = BitIsSet(opcode, 20); 3105e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (Rd == 15 || Rn == 15 || Rm == 15) 3106e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3107e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen break; 3108e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen default: 3109e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3110e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 3111e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3112e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the first operand. 3113e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t value = ReadCoreReg (Rn, &success); 3114e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 3115e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3116e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the Rm register content. 3117e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadCoreReg (Rm, &success); 3118e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen if (!success) 3119e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3120e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3121e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // Get the shift amount. 3122e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen uint32_t amt = Bits32(val, 7, 0); 3123e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3124e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 3125e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3126e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // The context specifies that an immediate is to be moved into Rd. 3127e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen EmulateInstruction::Context context; 3128e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.type = EmulateInstruction::eContextImmediate; 3129e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen context.SetNoArgs (); 3130e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 313110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3132e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return false; 3133e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen } 3134e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen return true; 3135e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen} 3136e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen 3137b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an 3138713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register. Optionally the address just above the highest of those locations 3139b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register. 3140b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool 31417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3142b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{ 3143b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0 3144b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // ARM pseudo code... 3145b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ConditionPassed() 3146b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3147b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice address = R[n]; 3148b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3149b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for i = 0 to 14 3150b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<i> == '1' then 3151b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice R[i] = MemA[address, 4]; address = address + 4; 3152b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if registers<15> == '1' then 3153b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice LoadWritePC (MemA[address, 4]); 3154b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3155b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3156b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3157b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3158b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif 3159b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3160b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool success = false; 3161b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 31627bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3163b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3164b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t n; 3165b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice uint32_t registers = 0; 3166b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice bool wback; 3167b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3168b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice switch (encoding) 3169b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3170b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT1: 3171bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3172b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 10, 8); 3173b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 7, 0); 3174b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3175b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsClear (registers, n); 3176b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 3177b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitCount(registers) < 1) 3178b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3179b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3180b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingT2: 3181bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101' then SEE POP; 3182bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3183b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 3184b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 3185b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is zero. 3186b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 3187b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3188bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3189b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 3190b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 2) 3191b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3192b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3193b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3194bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3195098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3196b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3197b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3198bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 3199b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback 3200b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice && BitIsSet (registers, n)) 3201b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3202b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3203b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 3204b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice case eEncodingA1: 3205b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice n = Bits32 (opcode, 19, 16); 3206b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice registers = Bits32 (opcode, 15, 0); 3207b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice wback = BitIsSet (opcode, 21); 3208b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if ((n == 15) 3209b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice || (BitCount (registers) < 1)) 3210b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3211b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice break; 3212b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice default: 3213b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3214b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3215b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3216b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice int32_t offset = 0; 3217b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3218b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3219b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 322085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 32219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 32229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 32249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 32259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3226b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3227b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice for (int i = 0; i < 14; ++i) 3228b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3229b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, i)) 3230b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 323185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3233b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && (n == 13)) // Pop Instruction 3234b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice context.type = EmulateInstruction::eContextPopRegisterOffStack; 3235b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3236b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[i] = MemA [address, 4]; address = address + 4; 3237cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3238b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3239b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3240b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3241b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3242b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3243b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3244b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice offset += addr_byte_size; 3245b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3246b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3247b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3248b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (BitIsSet (registers, 15)) 3249b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3250b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //LoadWritePC (MemA [address, 4]); 325185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 32529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3253cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3254b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!success) 3255b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3256e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3257668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3258b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3259b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3260b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3261b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsClear (registers, n)) 3262b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 3263fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // R[n] = R[n] + 4 * BitCount (registers) 3264fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = addr_byte_size * BitCount (registers); 3265fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 32669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3267b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3268b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3269b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return false; 3270b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3271b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice if (wback && BitIsSet (registers, n)) 3272b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // R[n] bits(32) UNKNOWN; 3273713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3274b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice } 3275b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice return true; 3276b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice} 3277713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3278bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3279bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// The consecutive memory locations end at this address and the address just below the lowest of those locations 3280bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// can optionally be written back to the base register. 3281713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool 32827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3283713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{ 3284713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0 3285713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // ARM pseudo code... 3286713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ConditionPassed() then 3287713c2665a27096b68f3f8956222375354f1292f8Caroline Tice EncodingSpecificOperations(); 3288713c2665a27096b68f3f8956222375354f1292f8Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 3289713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3290713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for i = 0 to 14 3291bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 3292713c2665a27096b68f3f8956222375354f1292f8Caroline Tice R[i] = MemA[address,4]; address = address + 4; 3293713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3294bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 3295713c2665a27096b68f3f8956222375354f1292f8Caroline Tice LoadWritePC(MemA[address,4]); 3296713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3297bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3298bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3299713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif 3300713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3301713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool success = false; 3302713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 33037bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3304713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3305713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t n; 3306713c2665a27096b68f3f8956222375354f1292f8Caroline Tice uint32_t registers = 0; 3307713c2665a27096b68f3f8956222375354f1292f8Caroline Tice bool wback; 3308713c2665a27096b68f3f8956222375354f1292f8Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3309713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3310713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // EncodingSpecificOperations(); 3311713c2665a27096b68f3f8956222375354f1292f8Caroline Tice switch (encoding) 3312713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3313713c2665a27096b68f3f8956222375354f1292f8Caroline Tice case eEncodingA1: 3314bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3315713c2665a27096b68f3f8956222375354f1292f8Caroline Tice n = Bits32 (opcode, 19, 16); 3316713c2665a27096b68f3f8956222375354f1292f8Caroline Tice registers = Bits32 (opcode, 15, 0); 3317713c2665a27096b68f3f8956222375354f1292f8Caroline Tice wback = BitIsSet (opcode, 21); 3318b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice 3319713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3320713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 3321713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3322713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3323713c2665a27096b68f3f8956222375354f1292f8Caroline Tice break; 3324713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3325713c2665a27096b68f3f8956222375354f1292f8Caroline Tice default: 3326713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3327713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3328713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 3329713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3330713c2665a27096b68f3f8956222375354f1292f8Caroline Tice int32_t offset = 0; 3331bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 3332713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3333713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3334713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3335713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3336bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3337713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 33389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 33399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 33409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 33419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 33429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3343713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3344713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // for i = 0 to 14 3345713c2665a27096b68f3f8956222375354f1292f8Caroline Tice for (int i = 0; i < 14; ++i) 3346713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3347bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 3348713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, i)) 3349713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3350713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // R[i] = MemA[address,4]; address = address + 4; 3351bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3352cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3353713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3354713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3355713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3356713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3357713c2665a27096b68f3f8956222375354f1292f8Caroline Tice offset += addr_byte_size; 3358713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3359713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3360713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3361bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 3362713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // LoadWritePC(MemA[address,4]); 3363713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (BitIsSet (registers, 15)) 3364713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 33659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3366cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3367713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3368713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 336944c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen // In ARMv5T and above, this is an interworking branch. 3370668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3371713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3372713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3373713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3374bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3375713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsClear (registers, n)) 3376713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 3377713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3378713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3379fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3380fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3381fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 33829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3383bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 3384713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3385713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3386713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3387713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3388bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3389713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (wback && BitIsSet (registers, n)) 3390713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 3391713c2665a27096b68f3f8956222375354f1292f8Caroline Tice } 3392713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return true; 3393713c2665a27096b68f3f8956222375354f1292f8Caroline Tice} 3394713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3395713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3396713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3397713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register. 33980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool 33997bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 34000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{ 34010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0 34020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // ARM pseudo code... 34030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ConditionPassed() then 34040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 34050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice address = R[n] - 4*BitCount(registers); 34060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for i = 0 to 14 3408bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 34090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice R[i] = MemA[address,4]; address = address + 4; 3410bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 34110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice LoadWritePC(MemA[address,4]); 34120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3413bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3414bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 34150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif 34160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool success = false; 34180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34197bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 34200b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34210b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t n; 34220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice uint32_t registers = 0; 34230b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice bool wback; 34240b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 34250b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice switch (encoding) 34260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingT1: 3428bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 34290b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 34300b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 3431b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0xdfff; // Make sure bit 13 is a zero. 34320b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 34330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3434bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 34350b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) 34360b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitCount (registers) < 2) 34370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 34380b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34390b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3440bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3441098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 34420b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34430b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3444bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 34450b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 34460b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 34490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice case eEncodingA1: 3451bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 34520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice n = Bits32 (opcode, 19, 16); 34530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice registers = Bits32 (opcode, 15, 0); 34540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice wback = BitIsSet (opcode, 21); 34550b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34560b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 34570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 34580b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34590b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice break; 34610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice default: 34630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 34650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3466713c2665a27096b68f3f8956222375354f1292f8Caroline Tice // address = R[n] - 4*BitCount(registers); 3467713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 34680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice int32_t offset = 0; 3469bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3470713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3471713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3472713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3473713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3474bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)); 34759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 34769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 34779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 34789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3479bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 34800b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice for (int i = 0; i < 14; ++i) 34820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, i)) 34840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 34850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 3486bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3487cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 34880b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 34890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 34920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 34930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 34940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice offset += addr_byte_size; 34950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 34960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 34970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3498bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 34990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice // LoadWritePC(MemA[address,4]); 35000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (BitIsSet (registers, 15)) 35010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 35029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3503cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 35040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 35050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3506e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3507668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 35080b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 35090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 35100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3511bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 35120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsClear (registers, n)) 35130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 35140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!success) 35150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 3516fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3517fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 3518fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 35199bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3520bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 35210b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 35220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return false; 35230b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 35240b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3525bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 35260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice if (wback && BitIsSet (registers, n)) 3527713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 35280b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice } 35290b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice return true; 35300b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice} 353185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3532713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3533713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3534713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register. 353585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool 35367bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 353785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{ 353885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0 353985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ConditionPassed() then 354085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice EncodingSpecificOperations(); 354185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice address = R[n] + 4; 354285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 354385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for i = 0 to 14 3544bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 354585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice R[i] = MemA[address,4]; address = address + 4; 3546bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 354785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice LoadWritePC(MemA[address,4]); 354885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3549bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3550bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 355185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif 355285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 355385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool success = false; 355485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 35557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 355685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 355785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t n; 355885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice uint32_t registers = 0; 355985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice bool wback; 356085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 356185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice switch (encoding) 356285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 356385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice case eEncodingA1: 3564bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 356585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice n = Bits32 (opcode, 19, 16); 356685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice registers = Bits32 (opcode, 15, 0); 356785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice wback = BitIsSet (opcode, 21); 356885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 356985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 357085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if ((n == 15) || (BitCount (registers) < 1)) 357185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 357285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 357385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice break; 357485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice default: 357585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 357685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 357785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // address = R[n] + 4; 357885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 357985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice int32_t offset = 0; 3580bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3581713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3582713c2665a27096b68f3f8956222375354f1292f8Caroline Tice if (!success) 3583713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return false; 3584713c2665a27096b68f3f8956222375354f1292f8Caroline Tice 3585bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn + addr_byte_size; 358685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 35879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 35889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterPlusOffset; 35899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register dwarf_reg; 35909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 35919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 359285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 359385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice for (int i = 0; i < 14; ++i) 359485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 359585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, i)) 359685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 359785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // R[i] = MemA[address,4]; address = address + 4; 359885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3599bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3600cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 360185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 360285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 360385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 360485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 360585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 360685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 360785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice offset += addr_byte_size; 360885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 360985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 361085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3611bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 361285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice // LoadWritePC(MemA[address,4]); 361385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (BitIsSet (registers, 15)) 361485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 36159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (dwarf_reg, offset); 3616cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 361785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 361885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3619e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen // In ARMv5T and above, this is an interworking branch. 3620668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 362185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 362285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 362385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3624bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 362585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsClear (registers, n)) 362685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 362785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!success) 362885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 3629fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3630fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3631fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 36329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3633bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t addr = Rn + offset; 363485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 363585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return false; 363685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 363785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice 3638bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 363985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice if (wback && BitIsSet (registers, n)) 3640713c2665a27096b68f3f8956222375354f1292f8Caroline Tice return WriteBits32Unknown (n); 364185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice } 364285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice return true; 364385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice} 36440b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice 3645ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and 3646ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register. 3647ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb) 3648ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 36497bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3650ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 3651ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0 3652ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // ARM pseudo code... 3653ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (ConditionPassed()) 3654ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3655ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3656ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3657ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = if index then offset_addr else R[n]; 3658ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen data = MemU[address,4]; 3659ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if wback then R[n] = offset_addr; 3660ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if t == 15 then 3661ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3662ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen elsif UnalignedSupport() || address<1:0> = '00' then 3663ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen R[t] = data; 3664ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3665ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3666ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif 3667ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3668ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool success = false; 3669ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 36707bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3671ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3672ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rt; // the destination register 3673ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t Rn; // the base register 3674ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t imm32; // the immediate offset used to form the address 3675ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t offset_addr; // the offset address 3676ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen addr_t address; // the calculated address 3677ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen uint32_t data; // the literal data value from memory load 3678ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen bool add, index, wback; 3679ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen switch (encoding) { 3680baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT1: 3681baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32(opcode, 5, 3); 3682baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32(opcode, 2, 0); 3683baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3684baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE 3685baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3686baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3687baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3688baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3689baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3690baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3691baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT2: 3692bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3693baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 10, 8); 3694baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = 13; 3695baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 3696baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3697baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 3698baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3699baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3700baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3701baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3702baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3703baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3704baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT3: 3705bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 3706baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3707baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 15, 12); 3708baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32 (opcode, 19, 16); 3709baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 11, 0); 3710baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3711baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 3712baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = true; 3713baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = true; 3714baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = false; 3715baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3716baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3717baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3718baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3719baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3720baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3721baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3722baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice case eEncodingT4: 3723bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 3724bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3725bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3726bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 3727baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3728baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3729baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3730baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3731baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rt = Bits32 (opcode, 15, 12); 3732baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Rn = Bits32 (opcode, 19, 16); 3733baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice imm32 = Bits32 (opcode, 7, 0); 3734baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3735bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3736baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice index = BitIsSet (opcode, 10); 3737baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice add = BitIsSet (opcode, 9); 3738baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice wback = BitIsSet (opcode, 8); 3739baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3740baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3741baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3742baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3743baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3744baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice break; 3745baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice 3746baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice default: 3747baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice return false; 3748ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3749baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice uint32_t base = ReadCoreReg (Rn, &success); 3750ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3751ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3752ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (add) 3753ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base + imm32; 3754ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3755ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen offset_addr = base - imm32; 3756ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3757ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen address = (index ? offset_addr : base); 3758ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3759baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice Register base_reg; 3760baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 3761ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (wback) 3762ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 37639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context ctx; 3764baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3765baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 37669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 3767ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3768ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3769ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3770ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3771ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Prepare to write to the Rt register. 37729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 3773baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice context.type = EmulateInstruction::eContextRegisterLoad; 3774baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3775ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3776ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen // Read memory from the address. 3777cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice data = MemURead(context, address, 4, 0, &success); 3778ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!success) 3779ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3780ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3781ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Rt == 15) 3782ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3783ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (Bits32(address, 1, 0) == 0) 3784ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3785668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen if (!LoadWritePC(context, data)) 3786ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3787ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3788ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3789ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3790ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3791ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3792ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 3793ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3794ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return false; 3795ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3796ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen else 3797baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice WriteBits32Unknown (Rt); 3798ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen } 3799ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return true; 3800ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 3801ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 3802af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3803af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start at this address, and teh address just above the last 3804af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 3805fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool 38067bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 3807fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{ 3808fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0 3809fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ConditionPassed() then 3810fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3811fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = R[n]; 3812fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3813fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for i = 0 to 14 3814bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 3815fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 3816fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3817fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 3818fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = R[i]; 3819fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice address = address + 4; 3820fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3821bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then // Only possible for encoding A1 3822fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice MemA[address,4] = PCStoreValue(); 3823fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 3824fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif 3825fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3826fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool success = false; 3827fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 38287bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 3829fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3830fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t n; 3831fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t registers = 0; 3832fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice bool wback; 3833fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 3834fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3835fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3836fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice switch (encoding) 3837fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3838fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT1: 3839bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 3840fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 10, 8); 3841fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 7, 0); 3842b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3843fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = true; 3844fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3845fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if BitCount(registers) < 1 then UNPREDICTABLE; 3846fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitCount (registers) < 1) 3847fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3848fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3849fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3850fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3851fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingT2: 3852bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 3853fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 3854fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 3855b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3856fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 3857fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3858fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3859fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 2)) 3860fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3861fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3862bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 3863fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback && BitIsSet (registers, n)) 3864fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3865fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3866fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3867fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3868fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice case eEncodingA1: 3869bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3870fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice n = Bits32 (opcode, 19, 16); 3871fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice registers = Bits32 (opcode, 15, 0); 3872fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice wback = BitIsSet (opcode, 21); 3873fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3874fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3875fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 3876fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3877fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3878fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice break; 3879fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3880fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice default: 3881fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3882fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3883fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3884fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = R[n]; 3885fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice int32_t offset = 0; 3886fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3887fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3888fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3889fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 38909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice EmulateInstruction::Context context; 38919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 38929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register base_reg; 38939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3894fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3895fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // for i = 0 to 14 3896bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice int lowest_set_bit = 14; 3897fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice for (int i = 0; i < 14; ++i) 3898fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3899bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 3900fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, i)) 3901fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3902fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (i < lowest_set_bit) 3903fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice lowest_set_bit = i; 3904fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 3905fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 3906fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3907fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice WriteBits32UnknownToMemory (address + offset); 3908fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice else 3909fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3910fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = R[i]; 3911fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3912fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3913fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3914fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 39159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register data_reg; 39169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 39179bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3918cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3919fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3920fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3921fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3922fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // address = address + 4; 3923fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset += addr_byte_size; 3924fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3925fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3926fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3927bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then // Only possible for encoding A1 3928fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // MemA[address,4] = PCStoreValue(); 3929fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (BitIsSet (registers, 15)) 3930fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 39319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Register pc_reg; 39329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 39339bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 39348d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 3935fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!success) 3936fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3937fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 39388d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 3939fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3940fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3941fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3942fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 3943fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (wback) 3944fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 3945fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice offset = addr_byte_size * BitCount (registers); 3946fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 39479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice context.SetImmediateSigned (offset); 3948fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice addr_t data = address + offset; 3949fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3950fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return false; 3951fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3952fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice } 3953fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice return true; 3954fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice} 3955fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 3956af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 3957af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3958af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 39591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool 39607bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 39611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{ 39621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0 39631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ConditionPassed() then 39641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EncodingSpecificOperations(); 39651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = R[n] - 4*BitCount(registers) + 4; 39661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for i = 0 to 14 3968bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 39691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 39701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; 39711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 39721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = R[i]; 39731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice address = address + 4; 39741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 3975bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 39761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice MemA[address,4] = PCStoreValue(); 39771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 39791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif 39801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool success = false; 39821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39837bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 39841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 39851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t n; 39861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t registers = 0; 39871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice bool wback; 39881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 39891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // EncodingSpecificOperations(); 39911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice switch (encoding) 39921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 39931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice case eEncodingA1: 3994bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 39951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice n = Bits32 (opcode, 19, 16); 39961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice registers = Bits32 (opcode, 15, 0); 39971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice wback = BitIsSet (opcode, 21); 39981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 39991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 40001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((n == 15) || (BitCount (registers) < 1)) 40011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice break; 40031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice default: 40041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40071511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = R[n] - 4*BitCount(registers) + 4; 40081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice int32_t offset = 0; 4009bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 40101511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 40111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4013bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 40141511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice EmulateInstruction::Context context; 40161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 40171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register base_reg; 40181511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 40191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // for i = 0 to 14 4021bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice int lowest_bit_set = 14; 40221511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice for (int i = 0; i < 14; ++i) 40231511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4024bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 40251511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, i)) 40261511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 40271511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (i < lowest_bit_set) 40281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice lowest_bit_set = i; 40291511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice //if i == n && wback && i != LowestSetBit(registers) then 40301511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if ((i == n) && wback && (i != lowest_bit_set)) 40311511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; 40321511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice WriteBits32UnknownToMemory (address + offset); 40331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice else 40341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 40351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = R[i]; 40361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 40371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 40381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register data_reg; 40411511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4042bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4043cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 40441511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40451511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40461511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40471511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // address = address + 4; 40481511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice offset += addr_byte_size; 40491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4052bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 40531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // MemA[address,4] = PCStoreValue(); 40541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (BitIsSet (registers, 15)) 40551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 40561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice Register pc_reg; 40571511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 40581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 40598d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 40601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!success) 40611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40638d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 40641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 40671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 40681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (wback) 40691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 4070af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 40711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 40721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice context.SetImmediateSigned (offset); 4073bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 40741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 40751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return false; 40761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice } 40781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice return true; 40791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice} 40801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 4081af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4082af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations end just below this address, and the address of the first of 4083af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register. 4084b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool 40857bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4086b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{ 4087b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0 4088b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ConditionPassed() then 4089b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4090b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = R[n] - 4*BitCount(registers); 4091b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4092b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for i = 0 to 14 4093bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4094b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if i == n && wback && i != LowestSetBit(registers) then 4095b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4096b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 4097b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = R[i]; 4098b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice address = address + 4; 4099b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4100bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then // Only possible for encoding A1 4101b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice MemA[address,4] = PCStoreValue(); 4102b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4103b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if wback then R[n] = R[n] - 4*BitCount(registers); 4104b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif 4105b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4106b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4107b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool success = false; 4108b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 41097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4110b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4111b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t n; 4112b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t registers = 0; 4113b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice bool wback; 4114b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4115b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4116b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4117b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice switch (encoding) 4118b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4119b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingT1: 4120bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101' then SEE PUSH; 4121b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4122b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4123b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See PUSH 4124b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4125bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4126b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 4127b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 4128b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4129b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 4130b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4131b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 2) 4132b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4133bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if wback && registers<n> == '1' then UNPREDICTABLE; 4134b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback && BitIsSet (registers, n)) 4135b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4136b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 4137b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4138b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice case eEncodingA1: 4139bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH; 4140b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4141b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4142b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // See Push 4143b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4144bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4145b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice n = Bits32 (opcode, 19, 16); 4146b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice registers = Bits32 (opcode, 15, 0); 4147b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice wback = BitIsSet (opcode, 21); 4148b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4149b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((n == 15) || BitCount (registers) < 1) 4150b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4151b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice break; 4152b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4153b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice default: 4154b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4155b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4156b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4157b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = R[n] - 4*BitCount(registers); 4158b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4159b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice int32_t offset = 0; 4160bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4161b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4162b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4163b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4164bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4165b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4166b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice EmulateInstruction::Context context; 4167b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4168b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register base_reg; 4169b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4170b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4171b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // for i = 0 to 14 4172bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice uint32_t lowest_set_bit = 14; 4173b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice for (int i = 0; i < 14; ++i) 4174b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4175bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4176b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, i)) 4177b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4178b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (i < lowest_set_bit) 4179b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice lowest_set_bit = i; 4180b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4181b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4182b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4183b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice WriteBits32UnknownToMemory (address + offset); 4184b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice else 4185b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4186b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = R[i]; 4187b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4188b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4189b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4190b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4191b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register data_reg; 4192b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4193bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4194cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4195b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4196b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4197b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4198b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // address = address + 4; 4199b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset += addr_byte_size; 4200b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4201b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4202b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4203bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then // Only possible for encoding A1 4204b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // MemA[address,4] = PCStoreValue(); 4205b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (BitIsSet (registers, 15)) 4206b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4207b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice Register pc_reg; 4208b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 4209b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 42108d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4211b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!success) 4212b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4213b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 42148d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4215b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4216b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4217b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 4218b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice // if wback then R[n] = R[n] - 4*BitCount(registers); 4219b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (wback) 4220b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 4221af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset = (addr_byte_size * BitCount (registers)) * -1; 4222af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 4223af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetImmediateSigned (offset); 4224bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 4225af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4226af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4227af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4228af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4229af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return true; 4230af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice} 4231af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4232af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4233af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register. The consecutive memory locations start just above this address, and the address of the last 4234af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register. 4235af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool 42367bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4237af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{ 4238af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0 4239af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ConditionPassed() then 4240af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EncodingSpecificOperations(); 4241af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = R[n] + 4; 4242af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4243af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for i = 0 to 14 4244bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<i> == '1' then 4245af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if i == n && wback && i != LowestSetBit(registers) then 4246af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = bits(32) UNKNOWN; 4247af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 4248af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = R[i]; 4249af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice address = address + 4; 4250af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4251bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if registers<15> == '1' then 4252af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice MemA[address,4] = PCStoreValue(); 4253af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4254af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if wback then R[n] = R[n] + 4*BitCount(registers); 4255af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif 4256af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4257af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool success = false; 4258af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 42597bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 4260af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4261af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t n; 4262af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t registers = 0; 4263af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice bool wback; 4264af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 4265af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4266af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // EncodingSpecificOperations(); 4267af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice switch (encoding) 4268af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4269af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice case eEncodingA1: 4270bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4271af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice n = Bits32 (opcode, 19, 16); 4272af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice registers = Bits32 (opcode, 15, 0); 4273af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice wback = BitIsSet (opcode, 21); 4274af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4275af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4276af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((n == 15) && (BitCount (registers) < 1)) 4277af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4278af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice break; 4279af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice default: 4280af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4281af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4282af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = R[n] + 4; 4283af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4284af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice int32_t offset = 0; 4285bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t Rn = ReadCoreReg (n, &success); 4286af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4287af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4288af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4289bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t address = Rn + addr_byte_size; 4290af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4291af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice EmulateInstruction::Context context; 4292af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.type = EmulateInstruction::eContextRegisterStore; 4293af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register base_reg; 4294af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4295af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4296af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t lowest_set_bit = 14; 4297af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // for i = 0 to 14 4298af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice for (int i = 0; i < 14; ++i) 4299af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4300bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<i> == '1' then 4301af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, i)) 4302af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4303af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (i < lowest_set_bit) 4304af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice lowest_set_bit = i; 4305af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if i == n && wback && i != LowestSetBit(registers) then 4306af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if ((i == n) && wback && (i != lowest_set_bit)) 4307af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = bits(32) UNKNOWN; 4308af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice WriteBits32UnknownToMemory (address + offset); 4309af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // else 4310af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice else 4311af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4312af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = R[i]; 4313af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4314af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4315af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4316af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4317af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register data_reg; 4318af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4319bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4320cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4321af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4322af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4323af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4324af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // address = address + 4; 4325af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice offset += addr_byte_size; 4326af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4327af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4328af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4329bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if registers<15> == '1' then 4330af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // MemA[address,4] = PCStoreValue(); 4331af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (BitIsSet (registers, 15)) 4332af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4333af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice Register pc_reg; 4334af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 4335af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice context.SetRegisterPlusOffset (pc_reg, 8); 43368d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice const uint32_t pc = ReadCoreReg (PC_REG, &success); 4337af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (!success) 4338af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4339af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 43408d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4341af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice return false; 4342af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice } 4343af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 4344af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice // if wback then R[n] = R[n] + 4*BitCount(registers); 4345af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice if (wback) 4346af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 4347b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice offset = addr_byte_size * BitCount (registers); 4348b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.type = EmulateInstruction::eContextAdjustBaseRegister; 4349b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice context.SetImmediateSigned (offset); 4350bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice addr_t data = Rn + offset; 4351b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4352b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return false; 4353b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4354b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice } 4355b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice return true; 4356b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice} 43577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 43597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 43607fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool 43617bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 43627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{ 43637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0 43647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ConditionPassed() then 43657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 43667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 43677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = if index then offset_addr else R[n]; 4368bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<1:0> == '00' then 43697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = R[t]; 43707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else // Can only occur before ARMv7 43717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice MemU[address,4] = bits(32) UNKNOWN; 43727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if wback then R[n] = offset_addr; 43737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif 43747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool success = false; 43767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43777bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 43787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 43797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 43807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t t; 43827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t n; 43837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t imm32; 43847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool index; 43857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool add; 43867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice bool wback; 43877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 43887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice switch (encoding) 43897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 43907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT1: 4391bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 43927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 2, 0); 43937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 5, 3); 43947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 10, 6) << 2; 43957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 43967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 43977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 43987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = false; 43997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 44007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT2: 4403bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 44047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 10, 8); 44057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = 13; 44067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0) << 2; 44077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 44097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 44107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 44117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 44127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT3: 4415bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 44167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 44177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 44207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 44217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 44227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 11, 0); 44237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 44257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = true; 44267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = true; 44277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = false; 44287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 then UNPREDICTABLE; 44307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (t == 15) 44317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice case eEncodingT4: 4435bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE STRT; 4436bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4437bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 44387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((Bits32 (opcode, 19, 16) == 15) 44397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 44407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 44437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice t = Bits32 (opcode, 15, 12); 44447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice n = Bits32 (opcode, 19, 16); 44457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice imm32 = Bits32 (opcode, 7, 0); 44467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4447bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 44487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice index = BitIsSet (opcode, 10); 44497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice add = BitIsSet (opcode, 9); 44507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice wback = BitIsSet (opcode, 8); 44517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44527fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 44537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if ((t == 15) || (wback && (n == t))) 44547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice break; 44567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice default: 44587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 44607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t offset_addr; 44627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice addr_t address; 4463b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice 44647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4465baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice uint32_t base_address = ReadCoreReg (n, &success); 44667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 44677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (add) 44707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address + imm32; 44717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 44727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice offset_addr = base_address - imm32; 44737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // address = if index then offset_addr else R[n]; 44757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (index) 44767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = offset_addr; 44777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 44787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice address = base_address; 44797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice EmulateInstruction::Context context; 44817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterStore; 44827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice Register base_reg; 44837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 44847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 4485bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<1:0> == '00' then 44867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 44877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 44887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = R[t]; 44897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 44907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!success) 44917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 44937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice Register data_reg; 44947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 44957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice int32_t offset = address - base_address; 44967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4497cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 44987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 44997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice else 45017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 45027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // MemU[address,4] = bits(32) UNKNOWN; 45037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice WriteBits32UnknownToMemory (address); 45047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice 45067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice // if wback then R[n] = offset_addr; 45077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (wback) 45087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 45097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.type = eContextRegisterLoad; 45107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice context.SetAddress (offset_addr); 45117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 45127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return false; 45137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice } 45157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice return true; 45167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice} 4517af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice 45183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 45193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory. The offset register value can optionally be shifted. 45203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool 45217bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 45223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{ 45233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0 45243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ConditionPassed() then 45253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 45263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 45273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 45283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = if index then offset_addr else R[n]; 45293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if t == 15 then // Only possible for encoding A1 45303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = PCStoreValue(); 45313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 45323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = R[t]; 4533bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 45343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = data; 45353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else // Can only occur before ARMv7 45363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice MemU[address,4] = bits(32) UNKNOWN; 45373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if wback then R[n] = offset_addr; 45383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif 45393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool success = false; 45413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45427bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 45433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 45443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 45453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t t; 45473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t n; 45483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t m; 45493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice ARM_ShifterType shift_t; 45503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t shift_n; 45513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool index; 45523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool add; 45533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice bool wback; 45543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 45563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice switch (encoding) 45573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 45583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT1: 45593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 45603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 45613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 2, 0); 45623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 5, 3); 45633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 8, 6); 45643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 45663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 45673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 45683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 45693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 45713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 45723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = 0; 45733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 45743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingT2: 4576bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 45773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (Bits32 (opcode, 19, 16) == 15) 45783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 45793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 45813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 45823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 45833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 45843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 45863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = true; 45873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = true; 45883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = false; 45893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 45913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_t = SRType_LSL; 45923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = Bits32 (opcode, 5, 4); 45933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 || BadReg(m) then UNPREDICTABLE; 45953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if ((t == 15) || (BadReg (m))) 45963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 45973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 45983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 45993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice case eEncodingA1: 46003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 4601bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE STRT; 46023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 46033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice t = Bits32 (opcode, 15, 12); 46043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice n = Bits32 (opcode, 19, 16); 46053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice m = Bits32 (opcode, 3, 0); 46063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4607bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 46083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice index = BitIsSet (opcode, 24); 46093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice add = BitIsSet (opcode, 23); 46103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 46113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 46133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t typ = Bits32 (opcode, 6, 5); 46143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 46153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice shift_n = DecodeImmShift(typ, imm5, shift_t); 46163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if m == 15 then UNPREDICTABLE; 46183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (m == 15) 46193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 46223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback && ((n == 15) || (n == t))) 46233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice break; 46263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 46273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice default: 46283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 46303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t offset_addr; 46323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t address; 46333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice int32_t offset = 0; 46343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 46363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 46373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 46403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 46413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4644e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen offset = Shift (Rm_data, shift_t, shift_n, APSR_C); 46453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 46473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (add) 46483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address + offset; 46493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice offset_addr = base_address - offset; 46513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // address = if index then offset_addr else R[n]; 46533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (index) 46543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = offset_addr; 46553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice address = base_address; 46573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice uint32_t data; 46593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if t == 15 then // Only possible for encoding A1 46603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (t == 15) 46613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = PCStoreValue(); 46628d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice data = ReadCoreReg (PC_REG, &success); 46633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // data = R[t]; 46653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 46663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!success) 46683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice EmulateInstruction::Context context; 46713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterStore; 46723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 4673bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 46743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (UnalignedSupport () 46753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || (BitIsClear (address, 1) && BitIsClear (address, 0)) 46763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice || CurrentInstrSet() == eModeARM) 46773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 46783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = data; 46793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice Register base_reg; 46813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 46823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice Register data_reg; 46843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 46853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4687cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, addr_byte_size)) 46883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 46893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 46913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice else 46923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // MemU[address,4] = bits(32) UNKNOWN; 46933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice WriteBits32UnknownToMemory (address); 46943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 46953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice // if wback then R[n] = offset_addr; 46963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (wback) 46973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 46983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.type = eContextRegisterLoad; 46993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice context.SetAddress (offset_addr); 47003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 47013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return false; 47023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 47033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 47043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice } 47053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice return true; 47063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice} 470773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 470873a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool 47097bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 471073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{ 471173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0 471273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ConditionPassed() then 471373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 471473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 471573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = if index then offset_addr else R[n]; 471673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice MemU[address,1] = R[t]<7:0>; 471773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if wback then R[n] = offset_addr; 471873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif 471973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 472073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 472173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool success = false; 472273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 47237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 472473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 472573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t t; 472673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t n; 472773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t imm32; 472873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool index; 472973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool add; 473073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice bool wback; 473173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 473273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice switch (encoding) 473373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 473473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT1: 473573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 473673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 2, 0); 473773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 5, 3); 473873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 10, 6); 473973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 474073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 474173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 474273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 474373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 474473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 474573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 474673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT2: 4747bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 474873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 474973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 475073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 475173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 475273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 475373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 475473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 11, 0); 475573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 475673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 475773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = true; 475873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = true; 475973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = false; 476073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 476173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) then UNPREDICTABLE; 476273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (BadReg (t)) 476373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 476473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 476573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 476673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice case eEncodingT3: 4767bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4768bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 476973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (Bits32 (opcode, 19, 16) == 15) 477073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 477173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 477273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 477373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice t = Bits32 (opcode, 15, 12); 477473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice n = Bits32 (opcode, 19, 16); 477573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice imm32 = Bits32 (opcode, 7, 0); 477673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4777bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 477873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice index = BitIsSet (opcode, 10); 477973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice add = BitIsSet (opcode, 9); 478073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice wback = BitIsSet (opcode, 8); 478173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 478273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 478373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if ((BadReg (t)) || (wback && (n == t))) 478473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 478573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice break; 478673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 478773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice default: 478873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 478973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 479073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 479173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t offset_addr; 479273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t address; 479373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 479473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 479573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 479673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 479773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 479873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (add) 479973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address + imm32; 480073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 480173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice offset_addr = base_address - imm32; 480273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 480373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // address = if index then offset_addr else R[n]; 480473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (index) 480573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = offset_addr; 480673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice else 480773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice address = base_address; 480873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4809cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice // MemU[address,1] = R[t]<7:0> 481073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice Register base_reg; 481173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 481273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 481373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice Register data_reg; 481473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 481573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 481673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice EmulateInstruction::Context context; 481773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterStore; 481873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 481973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 482073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 482173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!success) 482273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 482373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 482473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice data = Bits32 (data, 7, 0); 482573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 4826cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice if (!MemUWrite (context, address, data, 1)) 482773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 482873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 482973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice // if wback then R[n] = offset_addr; 483073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (wback) 483173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice { 483273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.type = eContextRegisterLoad; 483373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice context.SetAddress (offset_addr); 483473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 483573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return false; 483673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 483773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 483873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice } 483973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice 484073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice return true; 484173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice} 48428ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// STRH (register) calculates an address from a base register value and an offset register value, and stores a 48448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 48458ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Ticebool 48467bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 48478ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice{ 48488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#if 0 48498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if ConditionPassed() then 48508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 48518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 48528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 48538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = if index then offset_addr else R[n]; 4854bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> == '0' then 48558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice MemU[address,2] = R[t]<15:0>; 48568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else // Can only occur before ARMv7 48578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice MemU[address,2] = bits(16) UNKNOWN; 48588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if wback then R[n] = offset_addr; 48598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#endif 48608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool success = false; 48628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 48648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 48658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t t; 48668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t n; 48678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t m; 48688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool index; 48698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool add; 48708ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice bool wback; 48718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice ARM_ShifterType shift_t; 48728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t shift_n; 48738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 48758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice switch (encoding) 48768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 48778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingT1: 48788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 48798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 48808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 2, 0); 48818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 5, 3); 48828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 8, 6); 48838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 48858ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = true; 48868ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = true; 48878ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = false; 48888ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 48908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 48918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = 0; 48928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 48948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 48958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingT2: 4896bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then UNDEFINED; 48978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 48988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 15, 12); 48998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 19, 16); 49008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 3, 0); 49018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (n == 15) 49028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49038ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 49058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = true; 49068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = true; 49078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = false; 49088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 49108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 49118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = Bits32 (opcode, 5, 4); 49128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 49148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (BadReg (t) || BadReg (m)) 49158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49178ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 49188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49198ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice case eEncodingA1: 4920bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE STRHT; 49218ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 49228ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice t = Bits32 (opcode, 15, 12); 49238ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice n = Bits32 (opcode, 19, 16); 49248ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice m = Bits32 (opcode, 3, 0); 49258ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 4926bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 49278ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice index = BitIsSet (opcode, 24); 49288ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice add = BitIsSet (opcode, 23); 49298ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 49308ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49318ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 49328ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_t = SRType_LSL; 49338ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice shift_n = 0; 49348ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49358ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 49368ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if ((t == 15) || (m == 15)) 49378ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49388ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49398ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 49408ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (wback && ((n == 15) || (n == t))) 49418ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49428ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice break; 49448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49458ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice default: 49468ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49478ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 49488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 49508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 49518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rn = ReadCoreReg (n, &success); 49548ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 49558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 49588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 49598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 49618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice addr_t offset_addr; 49628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (add) 49638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = Rn + offset; 49648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else 49658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_addr = Rn - offset; 49668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // address = if index then offset_addr else R[n]; 49688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice addr_t address; 49698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (index) 49708ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = offset_addr; 49718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else 49728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice address = Rn; 49738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EmulateInstruction::Context context; 49758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextRegisterStore; 49768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register base_reg; 49778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 49788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register offset_reg; 49798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 49808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 4981bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> == '0' then 49828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 49838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 49848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // MemU[address,2] = R[t]<15:0>; 49858ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice uint32_t Rt = ReadCoreReg (t, &success); 49868ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!success) 49878ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 49888ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice EmulateInstruction::Context context; 49908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextRegisterStore; 49918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register base_reg; 49928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 49938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register offset_reg; 49948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 49958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice Register data_reg; 49968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 49978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 49988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 49998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 50008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 50018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice else // Can only occur before ARMv7 50038ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 50048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // MemU[address,2] = bits(16) UNKNOWN; 50058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice // if wback then R[n] = offset_addr; 50088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (wback) 50098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 50108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.type = eContextAdjustBaseRegister; 50118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice context.SetAddress (offset_addr); 50128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 50138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return false; 50148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice } 50168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice 50178ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice return true; 50188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice} 50193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice 5020157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5021157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// and writes the result to the destination register. It can optionally update the condition flags 5022157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// based on the result. 5023157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 50247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5025157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 5026157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 5027157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 5028157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 5029157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 5030157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5031157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 5032157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5033157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 5034157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 5035157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 5036157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 5037157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 5038157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 5039157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 5040157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 5041157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5042157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 5043157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 50447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5045157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5046157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn; 5047157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5048157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 5049157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 5050157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5051157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 5052157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 5053157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5054157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 5055157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5056157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 5057157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5058157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5059157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 5060157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 5061157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5062157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 5063157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5064157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5065157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 5066157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5067157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5068157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 5069157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5070157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5071157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5072157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 5073157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 5074157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5075157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5076157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5077157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5078157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5079157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 5080157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5081157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 5082157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5083157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5084157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5085157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5086157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 5087157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 5088157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5089157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5090157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// register value, and writes the result to the destination register. It can optionally update the 5091157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// condition flags based on the result. 5092157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool 50937bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5094157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 5095157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0 5096157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // ARM pseudo code... 5097157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if ConditionPassed() then 5098157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EncodingSpecificOperations(); 5099157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5100157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5101157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if d == 15 then // Can only occur for ARM encoding 5102157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5103157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 5104157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen R[d] = result; 5105157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if setflags then 5106157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.N = result<31>; 5107157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.Z = IsZeroBit(result); 5108157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.C = carry; 5109157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen APSR.V = overflow; 5110157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif 5111157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5112157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool success = false; 5113157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 51147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5115157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5116157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t Rd, Rn, Rm; 5117157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen ARM_ShifterType shift_t; 5118157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5119157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen bool setflags; 5120157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen switch (encoding) 5121157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 5122157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT1: 5123157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5124157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 5, 3); 5125157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = !InITBlock(); 5126157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_t = SRType_LSL; 5127157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen shift_n = 0; 5128ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 5129157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingT2: 5130157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 11, 8); 5131157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5132157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 5133157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 51343dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5135157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5136157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5137157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5138157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen case eEncodingA1: 5139157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rd = Bits32(opcode, 15, 12); 5140157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rn = Bits32(opcode, 19, 16); 5141157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen Rm = Bits32(opcode, 3, 0); 5142157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen setflags = BitIsSet(opcode, 20); 51433dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 5144157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5145157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (Rd == 15 && setflags) 5146157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5147157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen break; 5148157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen default: 5149157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5150157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5151157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5152157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the first operand. 5153157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val1 = ReadCoreReg(Rn, &success); 5154157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5155157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5156157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5157157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // Read the second operand. 5158157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen int32_t val2 = ReadCoreReg(Rm, &success); 5159157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!success) 5160157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5161157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5162157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 5163157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5164157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5165157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen EmulateInstruction::Context context; 5166157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5167157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen context.SetNoArgs (); 5168157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5169157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5170157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return false; 5171157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 5172157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return true; 5173157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 5174157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 5175a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// This instruction adds an immediate value to the PC value to form a PC-relative address, 5176a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// and writes the result to the destination register. 5177a695f958db37c102d480a9c0780abec262ba8332Johnny Chenbool 51787bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5179a695f958db37c102d480a9c0780abec262ba8332Johnny Chen{ 5180a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#if 0 5181a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // ARM pseudo code... 5182a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if ConditionPassed() then 5183a695f958db37c102d480a9c0780abec262ba8332Johnny Chen EncodingSpecificOperations(); 5184a695f958db37c102d480a9c0780abec262ba8332Johnny Chen result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5185a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if d == 15 then // Can only occur for ARM encodings 5186a695f958db37c102d480a9c0780abec262ba8332Johnny Chen ALUWritePC(result); 5187a695f958db37c102d480a9c0780abec262ba8332Johnny Chen else 5188a695f958db37c102d480a9c0780abec262ba8332Johnny Chen R[d] = result; 5189a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#endif 5190a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5191a695f958db37c102d480a9c0780abec262ba8332Johnny Chen bool success = false; 5192a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 51937bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5194a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 5195a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t Rd; 5196a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5197a695f958db37c102d480a9c0780abec262ba8332Johnny Chen bool add; 5198a695f958db37c102d480a9c0780abec262ba8332Johnny Chen switch (encoding) 5199a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 5200a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT1: 5201a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 10, 8); 5202a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5203a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5204a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT2: 5205a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingT3: 5206a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 11, 8); 5207a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5208a695f958db37c102d480a9c0780abec262ba8332Johnny Chen add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5209a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (BadReg(Rd)) 5210a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5211a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5212a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingA1: 5213a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case eEncodingA2: 5214a695f958db37c102d480a9c0780abec262ba8332Johnny Chen Rd = Bits32(opcode, 15, 12); 5215a695f958db37c102d480a9c0780abec262ba8332Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5216a695f958db37c102d480a9c0780abec262ba8332Johnny Chen add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5217a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 5218a695f958db37c102d480a9c0780abec262ba8332Johnny Chen default: 5219a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5220a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 5221a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5222a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // Read the PC value. 5223a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t pc = ReadCoreReg(PC_REG, &success); 5224a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!success) 5225a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5226a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5227a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5228a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5229a695f958db37c102d480a9c0780abec262ba8332Johnny Chen EmulateInstruction::Context context; 5230a695f958db37c102d480a9c0780abec262ba8332Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5231a695f958db37c102d480a9c0780abec262ba8332Johnny Chen context.SetNoArgs (); 5232a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5233a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!WriteCoreReg(context, result, Rd)) 5234a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return false; 5235a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 5236a695f958db37c102d480a9c0780abec262ba8332Johnny Chen return true; 5237a695f958db37c102d480a9c0780abec262ba8332Johnny Chen} 5238a695f958db37c102d480a9c0780abec262ba8332Johnny Chen 5239e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5240e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result. 5241e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 52427bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5243e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 5244e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 5245e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 5246e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 5247e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 5248e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND imm32; 5249e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 5250e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5251e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 5252e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 5253e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 5254e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 5255e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 5256e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 5257e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 5258e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 5259e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5260e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 5261e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 52627bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5263e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5264e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn; 5265e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5266e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 5267e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5268e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 5269e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5270e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 5271e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 5272e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5273e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 5274e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5275de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (immediate); 5276e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 52777bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTSTImm(opcode, eEncodingT1); 5278e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5279e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5280e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5281e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 5282e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 5283e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5284e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 5285e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5286e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5287e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 5288e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5289e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5290e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 5291e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5292e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5293e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5294e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 5295157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5296e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5297e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5298e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5299e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & imm32; 5300e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5301e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 5302e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 5303e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 5304e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5305e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5306e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5307e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5308e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 5309e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 5310e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5311e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5312e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags 5313e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// based on the result. 5314e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool 53157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5316e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{ 5317e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0 5318e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // ARM pseudo code... 5319e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if ConditionPassed() then 5320e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EncodingSpecificOperations(); 5321e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5322e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen result = R[n] AND shifted; 5323e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if d == 15 then // Can only occur for ARM encoding 5324e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ALUWritePC(result); // setflags is always FALSE here 5325e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen else 5326e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen R[d] = result; 5327e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if setflags then 5328e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.N = result<31>; 5329e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.Z = IsZeroBit(result); 5330e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen APSR.C = carry; 5331e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // APSR.V unchanged 5332e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif 5333e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5334e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool success = false; 5335e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 53367bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5337e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5338e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t Rd, Rn, Rm; 5339e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen ARM_ShifterType shift_t; 5340e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5341e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen bool setflags; 5342e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t carry; 5343e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen switch (encoding) 5344e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 5345e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT1: 5346e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5347e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 5, 3); 5348e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = !InITBlock(); 5349e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_t = SRType_LSL; 5350e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen shift_n = 0; 5351ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 5352e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingT2: 5353e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 11, 8); 5354e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5355e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 5356e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 53573dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5358de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // if Rd == '1111' && S == '1' then SEE TST (register); 5359e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 53607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTSTReg(opcode, eEncodingT2); 5361e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5362e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5363e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5364e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen case eEncodingA1: 5365e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rd = Bits32(opcode, 15, 12); 5366e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rn = Bits32(opcode, 19, 16); 5367e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen Rm = Bits32(opcode, 3, 0); 5368e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen setflags = BitIsSet(opcode, 20); 53693dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 5370e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5371e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (Rd == 15 && setflags) 5372e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5373e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen break; 5374e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen default: 5375e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5376e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5377e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5378e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the first operand. 5379157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5380e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5381e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5382e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5383e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // Read the second operand. 5384157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 5385e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!success) 5386e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5387e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5388e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 5389e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen uint32_t result = val1 & shifted; 5390e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5391e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen EmulateInstruction::Context context; 5392e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.type = EmulateInstruction::eContextImmediate; 5393e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen context.SetNoArgs (); 5394e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5395e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5396e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return false; 5397e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen } 5398e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen return true; 5399e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen} 5400e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen 5401b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5402b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// immediate value, and writes the result to the destination register. It can optionally update the 5403b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// condition flags based on the result. 5404b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool 54057bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5406b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{ 5407b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0 5408b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // ARM pseudo code... 5409b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if ConditionPassed() then 5410b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EncodingSpecificOperations(); 5411b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen result = R[n] AND NOT(imm32); 5412b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if d == 15 then // Can only occur for ARM encoding 5413b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5414b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen else 5415b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen R[d] = result; 5416b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if setflags then 5417b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.N = result<31>; 5418b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.Z = IsZeroBit(result); 5419b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.C = carry; 5420b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // APSR.V unchanged 5421b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif 5422b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5423b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool success = false; 5424b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 54257bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5426b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5427b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t Rd, Rn; 5428b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5429b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool setflags; 5430b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5431b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen switch (encoding) 5432b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5433b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT1: 5434b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 11, 8); 5435b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5436b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5437b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5438b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 5439b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5440b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5441b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingA1: 5442b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 15, 12); 5443b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5444b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5445b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5446bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5447b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5448b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (Rd == 15 && setflags) 5449b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5450b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5451b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen default: 5452b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5453b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5454b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5455b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the first operand. 5456b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5457b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5458b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5459b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5460b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t result = val1 & ~imm32; 5461b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5462b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EmulateInstruction::Context context; 5463b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5464b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.SetNoArgs (); 5465b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5466b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5467b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5468b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5469b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return true; 5470b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen} 5471b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5472b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5473b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// optionally-shifted register value, and writes the result to the destination register. 5474b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// It can optionally update the condition flags based on the result. 5475b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool 54767bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5477b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{ 5478b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0 5479b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // ARM pseudo code... 5480b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if ConditionPassed() then 5481b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EncodingSpecificOperations(); 5482b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5483b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen result = R[n] AND NOT(shifted); 5484b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if d == 15 then // Can only occur for ARM encoding 5485b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ALUWritePC(result); // setflags is always FALSE here 5486b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen else 5487b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen R[d] = result; 5488b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if setflags then 5489b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.N = result<31>; 5490b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.Z = IsZeroBit(result); 5491b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen APSR.C = carry; 5492b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // APSR.V unchanged 5493b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif 5494b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5495b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool success = false; 5496b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 54977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5498b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5499b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t Rd, Rn, Rm; 5500b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen ARM_ShifterType shift_t; 5501b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 5502b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen bool setflags; 5503b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t carry; 5504b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen switch (encoding) 5505b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 5506b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT1: 5507b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 5508b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 5, 3); 5509b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = !InITBlock(); 5510b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_t = SRType_LSL; 5511b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = 0; 5512b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5513b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingT2: 5514b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 11, 8); 5515b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5516b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 3, 0); 5517b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5518b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 5519b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5520b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5521b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5522b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen case eEncodingA1: 5523b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rd = Bits32(opcode, 15, 12); 5524b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rn = Bits32(opcode, 19, 16); 5525b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen Rm = Bits32(opcode, 3, 0); 5526b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen setflags = BitIsSet(opcode, 20); 5527b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 5528bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5529b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 5530b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (Rd == 15 && setflags) 5531b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5532b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen break; 5533b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen default: 5534b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5535b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5536b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5537b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the first operand. 5538b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 5539b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5540b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5541b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5542b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // Read the second operand. 5543b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 5544b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!success) 5545b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5546b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5547b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 5548b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen uint32_t result = val1 & ~shifted; 5549b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5550b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen EmulateInstruction::Context context; 5551b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.type = EmulateInstruction::eContextImmediate; 5552b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen context.SetNoArgs (); 5553b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 5554b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5555b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return false; 5556b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen } 5557b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen return true; 5558b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen} 5559b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen 55604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5561e92b27c9262fd185359e6e2184b20d08953485f4Johnny Chen// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 55624d729c559d039181f250e0e3cd444fa73638f26fCaroline Ticebool 55637bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 55644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice{ 55654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#if 0 55664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if ConditionPassed() then 55674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EncodingSpecificOperations(); 55684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 55694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = if index then offset_addr else R[n]; 55704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = MemU[address,4]; 55714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if wback then R[n] = offset_addr; 55724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if t == 15 then 5573bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5574bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 55754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = data; 55764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else // Can only apply before ARMv7 55774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 55784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#endif 55794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool success = false; 55814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55827bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 55834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 55844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 55854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t t; 55874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t n; 55884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint32_t imm32; 55894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool index; 55904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool add; 55914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice bool wback; 55924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 55934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice switch (encoding) 55944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 55954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice case eEncodingA1: 5596bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 5597bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRT; 5598bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 55994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 56004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice t = Bits32 (opcode, 15, 12); 56014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice n = Bits32 (opcode, 19, 16); 56024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice imm32 = Bits32 (opcode, 11, 0); 56034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5604bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5605bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice index = BitIsSet (opcode, 24); 5606bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice add = BitIsSet (opcode, 23); 5607bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 56084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback && n == t then UNPREDICTABLE; 56104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback && (n == t)) 56114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice break; 56144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice default: 56164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t address; 56204d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice addr_t offset_addr; 56218d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice addr_t base_address = ReadCoreReg (n, &success); 56224d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 56234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 56264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (add) 56278d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice offset_addr = base_address + imm32; 56284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice offset_addr = base_address - imm32; 56304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // address = if index then offset_addr else R[n]; 56324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (index) 56334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = offset_addr; 56344d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56354d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice address = base_address; 56364d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56374d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // data = MemU[address,4]; 56384d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56394d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice Register base_reg; 56404d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 56414d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56424d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice EmulateInstruction::Context context; 56434d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56444d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 56454d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56464d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 56474d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!success) 56484d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56494d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56504d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if wback then R[n] = offset_addr; 56514d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (wback) 56524d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextAdjustBaseRegister; 56544d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetAddress (offset_addr); 56554d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 56564d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56574d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56584d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // if t == 15 then 56604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (t == 15) 56614d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 5662bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 56634d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 56644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // LoadWritePC (data); 56664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 56684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice LoadWritePC (context, data); 56694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 5673bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // elsif UnalignedSupport() || address<1:0> = '00' then 56744d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 56754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = data; 56774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetRegisterPlusOffset (base_reg, address - base_address); 56794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 56804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // else // Can only apply before ARMv7 56834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice else 56844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 56854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 56864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice data = ROR (data, Bits32 (address, 1, 0)); 56874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.type = eContextRegisterLoad; 56884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice context.SetImmediate (data); 56894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 56904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return false; 56914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 56934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice } 56944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice return true; 56954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice} 56964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice 5697fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5698fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5699fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Ticebool 57007bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5701fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice{ 5702fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#if 0 5703fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ConditionPassed() then 5704fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5705fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 5706fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5707fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = if index then offset_addr else R[n]; 5708fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = MemU[address,4]; 5709fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if wback then R[n] = offset_addr; 5710fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if t == 15 then 5711bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5712bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice elsif UnalignedSupport() || address<1:0> = '00' then 5713fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = data; 5714fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 5715fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if CurrentInstrSet() == InstrSet_ARM then 5716fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = ROR(data, 8*UInt(address<1:0>)); 5717fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5718fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice R[t] = bits(32) UNKNOWN; 5719fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#endif 5720fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5721fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool success = false; 5722fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 57237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 5724fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5725fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice const uint32_t addr_byte_size = GetAddressByteSize(); 5726fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5727fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t t; 5728fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t n; 5729fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t m; 5730fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool index; 5731fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool add; 5732fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice bool wback; 5733fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice ARM_ShifterType shift_t; 5734fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t shift_n; 5735fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5736fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice switch (encoding) 5737fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5738fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT1: 5739fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5740fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5741fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 2, 0); 5742fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 5, 3); 5743fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 8, 6); 5744fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5745fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5746fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5747fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5748fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5749fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5750fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 5751fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5752fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = 0; 5753fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5754fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5755fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5756fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingT2: 5757bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDR (literal); 5758fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5759fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5760fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5761fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5762fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5763fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 5764fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = true; 5765fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = true; 5766fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = false; 5767fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5768fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5769fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_t = SRType_LSL; 5770fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = Bits32 (opcode, 5, 4); 5771fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5772fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if BadReg(m) then UNPREDICTABLE; 5773fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BadReg (m)) 5774fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5775fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5776fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5777fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if ((t == 15) && InITBlock() && !LastInITBlock()) 5778fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5779fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5780fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5781fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5782fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice case eEncodingA1: 5783fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5784bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRT; 5785fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5786fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice t = Bits32 (opcode, 15, 12); 5787fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice n = Bits32 (opcode, 19, 16); 5788fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice m = Bits32 (opcode, 3, 0); 5789fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5790bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5791fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice index = BitIsSet (opcode, 24); 5792fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice add = BitIsSet (opcode, 23); 5793fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5794fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5795fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5796fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 5797fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 5798fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 5799fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5800fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if m == 15 then UNPREDICTABLE; 5801fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (m == 15) 5802fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5803fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5804fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5805fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback && ((n == 15) || (n == t))) 5806fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5807fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5808fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice break; 5809fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5810fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5811fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice default: 5812fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5813fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5814fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5815fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5816fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5817fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5818fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5819fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5820fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5821fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5822fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5823fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t offset_addr; 5824fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice addr_t address; 5825fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5826fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 5827b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C)); 5828fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5829fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5830fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (add) 5831fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn + offset; 5832fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5833fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice offset_addr = Rn - offset; 5834fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5835fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // address = if index then offset_addr else R[n]; 5836fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (index) 5837fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = offset_addr; 5838fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5839fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice address = Rn; 5840fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5841fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // data = MemU[address,4]; 5842fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice Register base_reg; 5843fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5844fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5845fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice EmulateInstruction::Context context; 5846fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5847fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5848fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5849fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5850fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!success) 5851fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5852fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5853fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if wback then R[n] = offset_addr; 5854fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (wback) 5855fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5856fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextAdjustBaseRegister; 5857fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetAddress (offset_addr); 5858fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5859fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5860fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5861fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 5862fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if t == 15 then 5863fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (t == 15) 5864fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5865bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5866fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5867fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5868fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5869fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5870fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice LoadWritePC (context, data); 5871fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5872fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5873fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5874fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5875bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // elsif UnalignedSupport() || address<1:0> = '00' then 5876fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5877fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5878fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = data; 5879fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5880fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 5881fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5882fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5883fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5884fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else // Can only apply before ARMv7 5885fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5886fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // if CurrentInstrSet() == InstrSet_ARM then 5887fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (CurrentInstrSet () == eModeARM) 5888fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5889fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = ROR(data, 8*UInt(address<1:0>)); 5890fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice data = ROR (data, Bits32 (address, 1, 0)); 5891fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.type = eContextRegisterLoad; 5892fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice context.SetImmediate (data); 5893fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5894fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return false; 5895fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5896fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice else 5897fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 5898fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice // R[t] = bits(32) UNKNOWN; 5899fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice WriteBits32Unknown (t); 5900fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5901fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5902fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice } 5903fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice return true; 5904fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice} 590521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 590621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice// LDRB (immediate, Thumb) 590721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Ticebool 59087bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 590921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice{ 591021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#if 0 591121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if ConditionPassed() then 591221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 591321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 591421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = if index then offset_addr else R[n]; 591521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 591621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if wback then R[n] = offset_addr; 591721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#endif 591821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 591921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool success = false; 592021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 59217bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 592221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 592321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t t; 592421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t n; 592521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t imm32; 592621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool index; 592721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool add; 592821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice bool wback; 592921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 593021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 593121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice switch (encoding) 593221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 593321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT1: 593421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 593521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 2, 0); 593621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 5, 3); 593721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 10, 6); 593821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 593921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 594021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 594121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 594221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback= false; 594321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 594421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 594521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 594621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT2: 5947bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 5948bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 594921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 595021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 595121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 595221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 11, 0); 595321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 595421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 595521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = true; 595621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = true; 595721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = false; 595821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 595921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if t == 13 then UNPREDICTABLE; 596021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (t == 13) 596121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 596221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 596321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 596421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 596521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice case eEncodingT3: 5966bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 5967bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 5968bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 5969bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 597021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 597121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 597221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 597321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 597421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice t = Bits32 (opcode, 15, 12); 597521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice n = Bits32 (opcode, 19, 16); 597621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice imm32 = Bits32 (opcode, 7, 0); 597721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 5978bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 597921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice index = BitIsSet (opcode, 10); 598021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice add = BitIsSet (opcode, 9); 598121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice wback = BitIsSet (opcode, 8); 598221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 598321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 598421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (BadReg (t) || (wback && (n == t))) 598521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 598621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 598721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice break; 598821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 598921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice default: 599021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 599121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 599221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 599321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 599421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 599521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 599621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 599721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t address; 599821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice addr_t offset_addr; 599921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 600021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 600121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (add) 600221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn + imm32; 600321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 600421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice offset_addr = Rn - imm32; 600521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 600621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // address = if index then offset_addr else R[n]; 600721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (index) 600821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = offset_addr; 600921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice else 601021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice address = Rn; 601121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 601221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 601321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice Register base_reg; 601421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice Register data_reg; 601521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 601621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 601721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 601821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice EmulateInstruction::Context context; 601921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextRegisterLoad; 602021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 602121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 602221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 602321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!success) 602421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 602521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 602621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 602721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 602821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice 602921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice // if wback then R[n] = offset_addr; 603021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (wback) 603121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 603221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.type = eContextAdjustBaseRegister; 603321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice context.SetAddress (offset_addr); 603421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 603521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return false; 603621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 603721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice } 603821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice return true; 603921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice} 6040f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6041f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6042f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// zero-extends it to form a 32-bit word and writes it to a register. 6043f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Ticebool 60447bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6045f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice{ 6046f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#if 0 6047f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if ConditionPassed() then 6048f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6049f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice base = Align(PC,4); 6050f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = if add then (base + imm32) else (base - imm32); 6051f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice R[t] = ZeroExtend(MemU[address,1], 32); 6052f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#endif 6053f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6054f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool success = false; 6055f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 60567bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6057f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 6058f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t t; 6059f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t imm32; 6060f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice bool add; 6061f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice switch (encoding) 6062f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 6063f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingT1: 6064bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6065bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6066f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 6067f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6068f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 6069f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6070f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 13 then UNPREDICTABLE; 6071f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 13) 6072f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6073f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6074f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 6075f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6076f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice case eEncodingA1: 6077bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6078f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice t = Bits32 (opcode, 15, 12); 6079f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6080f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice add = BitIsSet (opcode, 23); 6081f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6082f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // if t == 15 then UNPREDICTABLE; 6083f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (t == 15) 6084f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6085f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice break; 6086f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6087f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice default: 6088f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6089f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 6090f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6091f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // base = Align(PC,4); 60928d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6093f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 6094f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6095f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6096f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint32_t base = AlignPC (pc_val); 6097f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6098f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice addr_t address; 6099f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // address = if add then (base + imm32) else (base - imm32); 6100f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (add) 6101f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base + imm32; 6102f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice else 6103f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice address = base - imm32; 6104f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6105f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice // R[t] = ZeroExtend(MemU[address,1], 32); 6106f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice EmulateInstruction::Context context; 6107f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.type = eContextRelativeBranchImmediate; 6108f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice context.SetImmediate (address - base); 6109f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6110f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 6111f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!success) 6112f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6113f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice 6114f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6115f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return false; 6116f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice } 6117f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice return true; 6118f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice} 611930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 612030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 612130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 612230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// optionally be shifted. 612330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Ticebool 61247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 612530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice{ 612630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#if 0 612730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ConditionPassed() then 612830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 612930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 613030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 613130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = if index then offset_addr else R[n]; 613230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice R[t] = ZeroExtend(MemU[address,1],32); 613330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if wback then R[n] = offset_addr; 613430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#endif 613530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 613630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool success = false; 613730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 61387bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 613930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 614030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t t; 614130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t n; 614230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t m; 614330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool index; 614430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool add; 614530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice bool wback; 614630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice ARM_ShifterType shift_t; 614730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t shift_n; 614830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 614930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 615030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice switch (encoding) 615130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 615230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT1: 615330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 615430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 2, 0); 615530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 5, 3); 615630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 8, 6); 615730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 615830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 615930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 616030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 616130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 616230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 616330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 616430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 616530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = 0; 616630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 616730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 616830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingT2: 6169bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLD; 6170bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRB (literal); 617130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 617230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 617330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 617430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 617530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 617630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 617730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = true; 617830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = true; 617930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = false; 618030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 618130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 618230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_t = SRType_LSL; 618330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = Bits32 (opcode, 5, 4); 618430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 618530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 618630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 13) || BadReg (m)) 618730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 618830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 618930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 619030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice case eEncodingA1: 619130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 6192bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRBT; 619330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 619430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice t = Bits32 (opcode, 15, 12); 619530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice n = Bits32 (opcode, 19, 16); 619630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice m = Bits32 (opcode, 3, 0); 619730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 6198bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 619930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice index = BitIsSet (opcode, 24); 620030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice add = BitIsSet (opcode, 23); 620130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 620230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 620330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 620430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t type = Bits32 (opcode, 6, 5); 620530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t imm5 = Bits32 (opcode, 11, 7); 620630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice shift_n = DecodeImmShift (type, imm5, shift_t); 620730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 620830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 620930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if ((t == 15) || (m == 15)) 621030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 621130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 621230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 621330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback && ((n == 15) || (n == t))) 621430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 621530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 621630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice break; 621730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 621830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice default: 621930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 622030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 622130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 622230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset_addr; 622330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t address; 622430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 622530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 622630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 622730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 622830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 622930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 623030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 623130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 623230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 623330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 623430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 623530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 623630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 623730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (add) 623830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn + offset; 623930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 624030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice offset_addr = Rn - offset; 624130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 624230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // address = if index then offset_addr else R[n]; 624330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (index) 624430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = offset_addr; 624530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice else 624630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice address = Rn; 624730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 624830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // R[t] = ZeroExtend(MemU[address,1],32); 624930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice Register base_reg; 625030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 625130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 625230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice EmulateInstruction::Context context; 625330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextRegisterLoad; 625430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 625530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 625630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice uint64_t data = MemURead (context, address, 1, 0, &success); 625730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!success) 625830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 625930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 626030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 626130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 626230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice 626330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice // if wback then R[n] = offset_addr; 626430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (wback) 626530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 626630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.type = eContextAdjustBaseRegister; 626730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice context.SetAddress (offset_addr); 626830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 626930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return false; 627030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 627130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice } 627230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice return true; 627330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice} 62740491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62750491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 62760491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 62770491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// post-indexed, or pre-indexed addressing. 62780491b3b75e1b045ab548f77fd1f76035522debdeCaroline Ticebool 62797bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 62800491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice{ 62810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#if 0 62820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if ConditionPassed() then 62830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 62840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 62850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = if index then offset_addr else R[n]; 62860491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice data = MemU[address,2]; 62870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if wback then R[n] = offset_addr; 6288bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 62890491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice R[t] = ZeroExtend(data, 32); 62900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else // Can only apply before ARMv7 62910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice R[t] = bits(32) UNKNOWN; 62920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#endif 62930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62950491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool success = false; 62960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 62977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 62980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 62990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t t; 63000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t n; 63010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t imm32; 63020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool index; 63030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool add; 63040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice bool wback; 63050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 63070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice switch (encoding) 63080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 63090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT1: 6310bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 63110491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 2, 0); 63120491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 5, 3); 63130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 10, 6) << 1; 63140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 63160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = true; 63170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = true; 63180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = false; 63190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 63210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT2: 6323bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 6324bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 63250491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 63260491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 15, 12); 63270491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 19, 16); 63280491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 11, 0); 63290491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63300491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 63310491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = true; 63320491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = true; 63330491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = false; 63340491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63350491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if t == 13 then UNPREDICTABLE; 63360491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (t == 13) 63370491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63380491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 63390491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63400491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice case eEncodingT3: 6341bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 6342bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6343bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6344bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 63450491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 63460491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63470491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63480491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 63490491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice t = Bits32 (opcode, 15, 12); 63500491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice n = Bits32 (opcode, 19, 16); 63510491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice imm32 = Bits32 (opcode, 7, 0); 63520491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 6353bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 63540491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice index = BitIsSet (opcode, 10); 63550491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice add = BitIsSet (opcode, 9); 63560491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice wback = BitIsSet (opcode, 8); 63570491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63580491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 63590491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (BadReg (t) || (wback && (n == t))) 63600491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63610491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice break; 63620491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63630491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice default: 63640491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63650491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 63660491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63670491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 63680491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 63690491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!success) 63700491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63710491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63720491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice addr_t offset_addr; 63730491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice addr_t address; 63740491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63750491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (add) 63760491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = Rn + imm32; 63770491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else 63780491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice offset_addr = Rn - imm32; 63790491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63800491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // address = if index then offset_addr else R[n]; 63810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (index) 63820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = offset_addr; 63830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else 63840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice address = Rn; 63850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63860491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // data = MemU[address,2]; 63870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice Register base_reg; 63880491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 63890491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice EmulateInstruction::Context context; 63910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextRegisterLoad; 63920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 63930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 63950491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!success) 63960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 63970491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 63980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // if wback then R[n] = offset_addr; 63990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (wback) 64000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 64010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextAdjustBaseRegister; 64020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetAddress (offset_addr); 64030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 64040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 64050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice 6407bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 64080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (UnalignedSupport () || BitIsClear (address, 0)) 64090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 64100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // R[t] = ZeroExtend(data, 32); 64110491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.type = eContextRegisterLoad; 64120491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 64130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 64140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return false; 64150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice else // Can only apply before ARMv7 64170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 64180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice // R[t] = bits(32) UNKNOWN; 64190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice WriteBits32Unknown (t); 64200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice } 64220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice return true; 64230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice} 6424fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice 6425952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6426952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// zero-extends it to form a 32-bit word, and writes it to a register. 6427952b53892191222c56003cd60d8a4a71c4384aa7Caroline Ticebool 64287bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6429952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice{ 6430952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#if 0 6431952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if ConditionPassed() then 6432952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6433952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice base = Align(PC,4); 6434952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = if add then (base + imm32) else (base - imm32); 6435952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice data = MemU[address,2]; 6436bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 6437952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice R[t] = ZeroExtend(data, 32); 6438952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else // Can only apply before ARMv7 6439952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice R[t] = bits(32) UNKNOWN; 6440952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#endif 64410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6442952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice bool success = false; 6443952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 64447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6445952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6446952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t t; 6447952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm32; 6448952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice bool add; 6449952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6450952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6451952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice switch (encoding) 6452952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6453952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice case eEncodingT1: 6454bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 6455bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6456952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice t = Bits32 (opcode, 15, 12); 6457952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6458952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice add = BitIsSet (opcode, 23); 6459952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6460952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // if t == 13 then UNPREDICTABLE; 6461952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (t == 13) 6462952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6463952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6464952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice break; 6465952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6466952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice case eEncodingA1: 6467952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6468952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 6469952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 6470952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6471bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6472952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice t = Bits32 (opcode, 15, 12); 647340b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 6474952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice add = BitIsSet (opcode, 23); 6475952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6476952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // if t == 15 then UNPREDICTABLE; 6477952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (t == 15) 6478952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6479952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice break; 6480952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6481952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6482952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice default: 6483952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6484952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6485952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6486952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // base = Align(PC,4); 64878d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6488952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!success) 6489952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6490952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6491952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice addr_t base = AlignPC (pc_value); 6492952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice addr_t address; 6493952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6494952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // address = if add then (base + imm32) else (base - imm32); 6495952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (add) 6496952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = base + imm32; 6497952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else 6498952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice address = base - imm32; 6499952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6500952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // data = MemU[address,2]; 6501952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice Register base_reg; 6502952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 6503952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6504952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice EmulateInstruction::Context context; 6505952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.type = eContextRegisterLoad; 6506952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 6507952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6508952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 6509952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!success) 6510952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6511952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6512952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6513bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 6514952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (UnalignedSupport () || BitIsClear (address, 0)) 6515952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6516952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // R[t] = ZeroExtend(data, 32); 6517952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.type = eContextRegisterLoad; 6518952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 6519952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6520952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return false; 6521952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 6522952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6523952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice else // Can only apply before ARMv7 6524952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 6525952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice // R[t] = bits(32) UNKNOWN; 6526952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice WriteBits32Unknown (t); 6527952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6528952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice } 6529952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice return true; 6530952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice} 6531952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice 65320e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 65330e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 65340e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// be shifted left by 0, 1, 2, or 3 bits. 65350e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Ticebool 65367bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 65370e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice{ 65380e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#if 0 65390e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ConditionPassed() then 65400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 65410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 65420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 65430e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = if index then offset_addr else R[n]; 65440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice data = MemU[address,2]; 65450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if wback then R[n] = offset_addr; 6546bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 65470e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice R[t] = ZeroExtend(data, 32); 65480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else // Can only apply before ARMv7 65490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice R[t] = bits(32) UNKNOWN; 65500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#endif 65510e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65520e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool success = false; 65530e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65547bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 65550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 65560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t t; 65570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t n; 65580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t m; 65590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool index; 65600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool add; 65610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice bool wback; 65620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice ARM_ShifterType shift_t; 65630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint32_t shift_n; 65640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 65660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice switch (encoding) 65670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 65680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingT1: 65690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 65700e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 65710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 2, 0); 65720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 5, 3); 65730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 8, 6); 65740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 65760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = true; 65770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = true; 65780e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = false; 65790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 65810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 65820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = 0; 65830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 65850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingT2: 6587bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRH (literal); 6588bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 65890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 65900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 15, 12); 65910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 19, 16); 65920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 3, 0); 65930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65940e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 65950e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = true; 65960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = true; 65970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = false; 65980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 65990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 66000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 66010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = Bits32 (opcode, 5, 4); 66020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 66040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ((t == 13) || BadReg (m)) 66050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66060e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 66070e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66080e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice case eEncodingA1: 6609bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRHT; 66100e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 66110e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice t = Bits32 (opcode, 15, 12); 66120e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice n = Bits32 (opcode, 19, 16); 66130e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice m = Bits32 (opcode, 3, 0); 66140e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6615bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 66160e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice index = BitIsSet (opcode, 24); 66170e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice add = BitIsSet (opcode, 23); 66180e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 66190e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66200e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 66210e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_t = SRType_LSL; 66220e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice shift_n = 0; 66230e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66240e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 66250e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if ((t == 15) || (m == 15)) 66260e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66270e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66280e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 66290e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (wback && ((n == 15) || (n == t))) 66300e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66310e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66320e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice break; 66330e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66340e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice default: 66350e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66360e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 66370e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66380e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 66390e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 66410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 66420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66430e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 66450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66460e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t offset_addr; 66470e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice addr_t address; 66480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 66500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 66510e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 66520e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66530e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (add) 66550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = Rn + offset; 66560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else 66570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_addr = Rn - offset; 66580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // address = if index then offset_addr else R[n]; 66600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (index) 66610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = offset_addr; 66620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else 66630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice address = Rn; 66640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // data = MemU[address,2]; 66660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice Register base_reg; 66670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice Register offset_reg; 66680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 66690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 66700e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice EmulateInstruction::Context context; 66720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextRegisterLoad; 66730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 66740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 66750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!success) 66760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 66780e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // if wback then R[n] = offset_addr; 66790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (wback) 66800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 66810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextAdjustBaseRegister; 66820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetAddress (offset_addr); 66830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 66840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 66860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6687bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 66880e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 66890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 66900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // R[t] = ZeroExtend(data, 32); 66910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.type = eContextRegisterLoad; 66920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 66930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 66940e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return false; 66950e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 66960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice else // Can only apply before ARMv7 66970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 66980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice // R[t] = bits(32) UNKNOWN; 66990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice WriteBits32Unknown (t); 67000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 67010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice } 67020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice return true; 67030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice} 67040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 6705a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6706a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6707a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// or pre-indexed addressing. 6708a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Ticebool 67097bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6710a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice{ 6711a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#if 0 6712a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if ConditionPassed() then 6713a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6714a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6715a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = if index then offset_addr else R[n]; 6716a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 6717a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if wback then R[n] = offset_addr; 6718a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#endif 6719a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6720a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool success = false; 6721a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 67227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6723a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6724a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t t; 6725a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t n; 6726a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm32; 6727a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool index; 6728a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool add; 6729a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice bool wback; 6730a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6731a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6732a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice switch (encoding) 6733a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6734a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingT1: 6735bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6736bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6737a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6738a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6739a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6740a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice imm32 = Bits32 (opcode, 11, 0); 6741a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6742a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 6743a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = true; 6744a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = true; 6745a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = false; 6746a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6747a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if t == 13 then UNPREDICTABLE; 6748a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (t == 13) 6749a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6750a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6751a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6752a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6753a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingT2: 6754bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6755bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6756bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6757bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 6758a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6759a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6760a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6761a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6762a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6763a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6764a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice imm32 = Bits32 (opcode, 7, 0); 6765a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6766bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6767a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = BitIsSet (opcode, 10); 6768a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = BitIsSet (opcode, 9); 6769a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = BitIsSet (opcode, 8); 6770a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6771a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6772bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if (((t == 13) || ((t == 15) 6773bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6774bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice || (wback && (n == t))) 6775a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6776a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6777a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6778a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6779a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice case eEncodingA1: 6780a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6781bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6782bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSBT; 6783a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6784a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice t = Bits32 (opcode, 15, 12); 6785a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice n = Bits32 (opcode, 19, 16); 6786a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6787a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 6788a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 678940b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 6790a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6791bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6792a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice index = BitIsSet (opcode, 24); 6793a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice add = BitIsSet (opcode, 23); 6794a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6795a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6796a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 6797a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if ((t == 15) || (wback && (n == t))) 6798a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6799a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6800a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice break; 6801a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6802a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6803a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice default: 6804a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6805a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6806a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6807bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice uint64_t Rn = ReadCoreReg (n, &success); 6808a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!success) 6809a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6810a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6811a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice addr_t offset_addr; 6812a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice addr_t address; 6813a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6814a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6815a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (add) 6816a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = Rn + imm32; 6817a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice else 6818a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice offset_addr = Rn - imm32; 6819a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6820a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // address = if index then offset_addr else R[n]; 6821a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (index) 6822a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = offset_addr; 6823a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice else 6824a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice address = Rn; 6825a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6826a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 6827a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice Register base_reg; 6828a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 6829a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6830a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice EmulateInstruction::Context context; 6831a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.type = eContextRegisterLoad; 6832a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 6833a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6834a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 6835a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!success) 6836a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6837a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6838a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 6839a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 6840a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6841a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6842a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice // if wback then R[n] = offset_addr; 6843a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (wback) 6844a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 6845a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.type = eContextAdjustBaseRegister; 6846a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice context.SetAddress (offset_addr); 6847a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6848a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return false; 6849a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6850a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice } 6851a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice 6852a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice return true; 6853a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice} 68540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice 68555f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 68565f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// sign-extends it to form a 32-bit word, and writes tit to a register. 68575f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Ticebool 68587bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 68595f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice{ 68605f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#if 0 68615f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if ConditionPassed() then 68625f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 68635f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice base = Align(PC,4); 68645f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = if add then (base + imm32) else (base - imm32); 68655f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 68665f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#endif 68675f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68685f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice bool success = false; 68695f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68707bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 68715f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 68725f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t t; 68735f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm32; 68745f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice bool add; 68755f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68765f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 68775f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice switch (encoding) 68785f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 68795f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice case eEncodingT1: 6880bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6881bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 68825f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice t = Bits32 (opcode, 15, 12); 68835f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice imm32 = Bits32 (opcode, 11, 0); 68845f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice add = BitIsSet (opcode, 23); 68855f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68865f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // if t == 13 then UNPREDICTABLE; 68875f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (t == 13) 68885f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 68895f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68905f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice break; 68915f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 68925f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice case eEncodingA1: 68935f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 6894bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 68955f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice t = Bits32 (opcode, 15, 12); 68965f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 68975f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 689840b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 68995f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice add = BitIsSet (opcode, 23); 69005f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69015f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // if t == 15 then UNPREDICTABLE; 69025f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (t == 15) 69035f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69045f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69055f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice break; 69065f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 69075f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69085f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice default: 69095f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69105f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 69115f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69125f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // base = Align(PC,4); 69138d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 69145f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!success) 69155f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69165f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint64_t base = AlignPC (pc_value); 69175f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69185f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // address = if add then (base + imm32) else (base - imm32); 69195f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice addr_t address; 69205f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (add) 69215f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = base + imm32; 69225f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice else 69235f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice address = base - imm32; 69245f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69255f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 69265f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice Register base_reg; 69275f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 69285f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69295f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice EmulateInstruction::Context context; 69305f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice context.type = eContextRegisterLoad; 69315f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice context.SetRegisterPlusOffset (base_reg, address - base); 69325f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69335f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 69345f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!success) 69355f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69365f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 69375f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 69385f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 69395f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return false; 69405f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice } 69415f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice return true; 69425f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice} 69435f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice 6944672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 6945672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 6946672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// shifted left by 0, 1, 2, or 3 bits. 6947672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Ticebool 69487bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 6949672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice{ 6950672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#if 0 6951672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ConditionPassed() then 6952672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6953672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 6954672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6955672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = if index then offset_addr else R[n]; 6956672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice R[t] = SignExtend(MemU[address,1], 32); 6957672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if wback then R[n] = offset_addr; 6958672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#endif 6959672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6960672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool success = false; 6961672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 69627bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 6963672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 6964672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t t; 6965672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t n; 6966672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t m; 6967672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool index; 6968672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool add; 6969672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice bool wback; 6970672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice ARM_ShifterType shift_t; 6971672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint32_t shift_n; 6972672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6973672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6974672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice switch (encoding) 6975672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 6976672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingT1: 6977672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6978672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 2, 0); 6979672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 5, 3); 6980672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 8, 6); 6981672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6982672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 6983672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = true; 6984672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = true; 6985672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = false; 6986672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6987672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 6988672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 6989672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = 0; 6990672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6991672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 6992672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 6993672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingT2: 6994bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE PLI; 6995bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSB (literal); 6996672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6997672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 15, 12); 6998672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 19, 16); 6999672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 3, 0); 7000672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7001672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7002672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = true; 7003672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = true; 7004672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = false; 7005672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7006672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7007672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7008672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = Bits32 (opcode, 5, 4); 7009672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7010672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 7011672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ((t == 13) || BadReg (m)) 7012672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7013672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7014672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7015672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice case eEncodingA1: 7016bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSBT; 7017672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7018672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice t = Bits32 (opcode, 15, 12); 7019672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice n = Bits32 (opcode, 19, 16); 7020672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice m = Bits32 (opcode, 3, 0); 7021672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7022bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7023672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice index = BitIsSet (opcode, 24); 7024672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice add = BitIsSet (opcode, 23); 7025672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7026672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7027672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7028672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_t = SRType_LSL; 7029672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice shift_n = 0; 7030672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7031672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 7032672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if ((t == 15) || (m == 15)) 7033672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7034672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7035672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7036672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (wback && ((n == 15) || (n == t))) 7037672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7038672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice break; 7039672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7040672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice default: 7041672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7042672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7043672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7044672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7045672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7046672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7047672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7048672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7049672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 7050672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7051672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t offset_addr; 7052672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice addr_t address; 7053672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7054672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7055672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7056672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7057672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7058672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7059672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (add) 7060672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = Rn + offset; 7061672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice else 7062672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_addr = Rn - offset; 7063672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7064672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // address = if index then offset_addr else R[n]; 7065672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (index) 7066672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = offset_addr; 7067672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice else 7068672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice address = Rn; 7069672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7070672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // R[t] = SignExtend(MemU[address,1], 32); 7071672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice Register base_reg; 7072672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 7073672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice Register offset_reg; 7074672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 7075672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7076672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice EmulateInstruction::Context context; 7077672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.type = eContextRegisterLoad; 7078672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7079672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7080672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7081672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!success) 7082672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7083672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7084672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7085672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7086672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7087672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 7088672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice // if wback then R[n] = offset_addr; 7089672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (wback) 7090672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 7091672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.type = eContextAdjustBaseRegister; 7092672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice context.SetAddress (offset_addr); 7093672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7094672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return false; 7095672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7096672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice } 7097672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice return true; 7098672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice} 7099672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice 710078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 710178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 710278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// pre-indexed addressing. 710378fb5638da9c01a39443f3339ede2f02056822cfCaroline Ticebool 71047bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 710578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice{ 710678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#if 0 710778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if ConditionPassed() then 710878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 710978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 711078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = if index then offset_addr else R[n]; 711178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice data = MemU[address,2]; 711278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if wback then R[n] = offset_addr; 7113bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 711478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice R[t] = SignExtend(data, 32); 711578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else // Can only apply before ARMv7 711678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice R[t] = bits(32) UNKNOWN; 711778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#endif 711878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 711978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool success = false; 712078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 71217bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 712278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 712378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t t; 712478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t n; 712578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm32; 712678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool index; 712778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool add; 712878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice bool wback; 712978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 713078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 713178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice switch (encoding) 713278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 713378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingT1: 7134bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7135bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 713678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 713778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 713878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 713978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice imm32 = Bits32 (opcode, 11, 0); 714078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 714178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 714278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = true; 714378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = true; 714478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = false; 714578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 714678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if t == 13 then UNPREDICTABLE; 714778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (t == 13) 714878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 714978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 715078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 715178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 715278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingT2: 7153bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7154bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7155bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7156bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '0' then UNDEFINED; 715778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 715878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 715978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 716078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 716178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 716278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 716378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice imm32 = Bits32 (opcode, 7, 0); 716478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7165bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 716678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = BitIsSet (opcode, 10); 716778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = BitIsSet (opcode, 9); 716878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = BitIsSet (opcode, 8); 716978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 717078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 717178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (BadReg (t) || (wback && (n == t))) 717278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 717378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 717478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 717578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 717678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice case eEncodingA1: 717778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 7178bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7179bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSHT; 718078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 718178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice t = Bits32 (opcode, 15, 12); 718278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice n = Bits32 (opcode, 19, 16); 718378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm4H = Bits32 (opcode, 11,8); 718478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 718540b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 718678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7187bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 718878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice index = BitIsSet (opcode, 24); 718978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice add = BitIsSet (opcode, 23); 719078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 719178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 719278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if t == 15 || (wback && n == t) then UNPREDICTABLE; 719378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if ((t == 15) || (wback && (n == t))) 719478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 719578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 719678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice break; 719778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 719878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 719978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice default: 720078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 720178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 720278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 720378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 720478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 720578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!success) 720678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 720778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 720878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice addr_t offset_addr; 720978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (add) 721078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = Rn + imm32; 721178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else 721278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice offset_addr = Rn - imm32; 721378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 721478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // address = if index then offset_addr else R[n]; 721578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice addr_t address; 721678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (index) 721778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = offset_addr; 721878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else 721978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice address = Rn; 722078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 722178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // data = MemU[address,2]; 722278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice Register base_reg; 722378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 722478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 722578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice EmulateInstruction::Context context; 722678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextRegisterLoad; 722778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 722878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 722978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 723078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!success) 723178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 723278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 723378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // if wback then R[n] = offset_addr; 723478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (wback) 723578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 723678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextAdjustBaseRegister; 723778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetAddress (offset_addr); 723878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 723978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 724078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 724178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7242bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 724378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 724478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 724578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // R[t] = SignExtend(data, 32); 724678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 724778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.type = eContextRegisterLoad; 724878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 724978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 725078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return false; 725178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 725278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice else // Can only apply before ARMv7 725378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 725478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice // R[t] = bits(32) UNKNOWN; 725578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice WriteBits32Unknown (t); 725678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 725778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice } 725878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice return true; 725978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice} 726078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice 7261d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7262d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// sign-extends it to from a 32-bit word, and writes it to a register. 7263d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Ticebool 72647bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7265d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice{ 7266d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#if 0 7267d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if ConditionPassed() then 7268d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7269d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice base = Align(PC,4); 7270d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = if add then (base + imm32) else (base - imm32); 7271d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice data = MemU[address,2]; 7272bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 7273d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice R[t] = SignExtend(data, 32); 7274d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else // Can only apply before ARMv7 7275d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice R[t] = bits(32) UNKNOWN; 7276d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#endif 7277d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7278d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice bool success = false; 7279d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 72807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7281d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7282d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t t; 7283d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm32; 7284d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice bool add; 7285d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7286d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7287d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice switch (encoding) 7288d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7289d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice case eEncodingT1: 7290bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 7291bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7292d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice t = Bits32 (opcode, 15, 12); 7293d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice imm32 = Bits32 (opcode, 11, 0); 7294d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice add = BitIsSet (opcode, 23); 7295d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7296d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // if t == 13 then UNPREDICTABLE; 7297d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (t == 13) 7298d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7299d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7300d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice break; 7301d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7302d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice case eEncodingA1: 7303d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7304bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7305d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice t = Bits32 (opcode, 15, 12); 7306d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm4H = Bits32 (opcode, 11, 8); 7307d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint32_t imm4L = Bits32 (opcode, 3, 0); 730840b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice imm32 = (imm4H << 4) | imm4L; 7309d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice add = BitIsSet (opcode, 23); 7310d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7311d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // if t == 15 then UNPREDICTABLE; 7312d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (t == 15) 7313d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7314d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7315d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice break; 7316d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7317d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice default: 7318d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7319d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7320d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7321d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // base = Align(PC,4); 73228d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7323d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!success) 7324d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7325d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7326d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint64_t base = AlignPC (pc_value); 7327d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7328d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice addr_t address; 7329d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // address = if add then (base + imm32) else (base - imm32); 7330d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (add) 7331d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = base + imm32; 7332d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else 7333d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice address = base - imm32; 7334d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7335d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // data = MemU[address,2]; 7336d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice Register base_reg; 7337d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 7338d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7339d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice EmulateInstruction::Context context; 7340d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice context.type = eContextRegisterLoad; 7341d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice context.SetRegisterPlusOffset (base_reg, imm32); 7342d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7343d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 7344d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!success) 7345d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7346d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7347bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 7348d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 7349d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7350d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // R[t] = SignExtend(data, 32); 7351d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 7352d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7353d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return false; 7354d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7355d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice else // Can only apply before ARMv7 7356d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 7357d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice // R[t] = bits(32) UNKNOWN; 7358d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice WriteBits32Unknown (t); 7359d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7360d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice } 7361d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice return true; 7362d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice} 7363d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice 7364291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7365291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7366291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// shifted left by 0, 1, 2, or 3 bits. 7367291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Ticebool 73687bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7369291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice{ 7370291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#if 0 7371291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ConditionPassed() then 7372291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7373291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset = Shift(R[m], shift_t, shift_n, APSR.C); 7374291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7375291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = if index then offset_addr else R[n]; 7376291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice data = MemU[address,2]; 7377291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if wback then R[n] = offset_addr; 7378bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice if UnalignedSupport() || address<0> = '0' then 7379291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice R[t] = SignExtend(data, 32); 7380291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else // Can only apply before ARMv7 7381291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice R[t] = bits(32) UNKNOWN; 7382291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#endif 7383291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7384291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool success = false; 7385291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 73867bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7387291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7388291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t t; 7389291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t n; 7390291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t m; 7391291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool index; 7392291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool add; 7393291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice bool wback; 7394291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice ARM_ShifterType shift_t; 7395291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint32_t shift_n; 7396291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7397291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7398291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice switch (encoding) 7399291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7400291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingT1: 7401291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7402291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7403291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 2, 0); 7404291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 5, 3); 7405291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 8, 6); 7406291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7407291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7408291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = true; 7409291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = true; 7410291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = false; 7411291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7412291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7413291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7414291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = 0; 7415291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7416291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7417291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7418291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingT2: 7419bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE LDRSH (literal); 7420bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rt == '1111' then SEE "Unallocated memory hints"; 7421291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7422291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 15, 12); 7423291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 19, 16); 7424291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 3, 0); 7425291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7426291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // index = TRUE; add = TRUE; wback = FALSE; 7427291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = true; 7428291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = true; 7429291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = false; 7430291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7431291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7432291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7433291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = Bits32 (opcode, 5, 4); 7434291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7435291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if t == 13 || BadReg(m) then UNPREDICTABLE; 7436291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ((t == 13) || BadReg (m)) 7437291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7438291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7439291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7440291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7441291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice case eEncodingA1: 7442bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if P == '0' && W == '1' then SEE LDRSHT; 7443291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7444291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice t = Bits32 (opcode, 15, 12); 7445291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice n = Bits32 (opcode, 19, 16); 7446291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice m = Bits32 (opcode, 3, 0); 7447291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7448bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7449291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice index = BitIsSet (opcode, 24); 7450291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice add = BitIsSet (opcode, 23); 7451291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7452291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7453291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // (shift_t, shift_n) = (SRType_LSL, 0); 7454291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_t = SRType_LSL; 7455291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice shift_n = 0; 7456291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7457291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if t == 15 || m == 15 then UNPREDICTABLE; 7458291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if ((t == 15) || (m == 15)) 7459291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7460291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7461291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7462291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (wback && ((n == 15) || (n == t))) 7463291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7464291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7465291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7466291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7467291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice default: 7468291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice break; 7469291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7470291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7471291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7472291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7473291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7474291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7475291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7476291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7477291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7478291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7479291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7480291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 7481291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7482291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t offset_addr; 7483291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice addr_t address; 7484291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7485291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7486291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (add) 7487291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = Rn + offset; 7488291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else 7489291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_addr = Rn - offset; 7490291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7491291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // address = if index then offset_addr else R[n]; 7492291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (index) 7493291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = offset_addr; 7494291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else 7495291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice address = Rn; 7496291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7497291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // data = MemU[address,2]; 7498291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice Register base_reg; 7499291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 7500291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7501291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice Register offset_reg; 7502291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 7503291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7504291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice EmulateInstruction::Context context; 7505291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextRegisterLoad; 7506291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7507291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7508291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice uint64_t data = MemURead (context, address, 2, 0, &success); 7509291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!success) 7510291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7511291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7512291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // if wback then R[n] = offset_addr; 7513291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (wback) 7514291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7515291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextAdjustBaseRegister; 7516291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetAddress (offset_addr); 7517291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7518291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7519291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7520291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7521bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if UnalignedSupport() || address<0> = '0' then 7522291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (UnalignedSupport() || BitIsClear (address, 0)) 7523291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7524291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // R[t] = SignExtend(data, 32); 7525291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.type = eContextRegisterLoad; 7526291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7527291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7528291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice int64_t signed_data = llvm::SignExtend64<16>(data); 7529291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7530291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return false; 7531291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7532291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice else // Can only apply before ARMv7 7533291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 7534291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice // R[t] = bits(32) UNKNOWN; 7535291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice WriteBits32Unknown (t); 7536291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7537291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice } 7538291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice return true; 7539291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice} 75406bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75416bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 75426bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 75436bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Ticebool 75447bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 75456bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice{ 75466bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#if 0 75476bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if ConditionPassed() then 75486bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice EncodingSpecificOperations(); 75496bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotated = ROR(R[m], rotation); 75506bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice R[d] = SignExtend(rotated<7:0>, 32); 75516bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#endif 75526bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75536bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice bool success = false; 75546bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 75566bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 75576bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t d; 75586bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t m; 75596bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint32_t rotation; 75606bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75616bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // EncodingSpecificOperations(); 75626bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice switch (encoding) 75636bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 75646bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingT1: 75656bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 75666bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 2, 0); 75676bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 5, 3); 75686bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = 0; 75696bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75706bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 75716bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75726bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingT2: 7573bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 75746bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 11, 8); 75756bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 3, 0); 75766bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 75776bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75786bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 75796bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if (BadReg (d) || BadReg (m)) 75806bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 75816bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75826bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 75836bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75846bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice case eEncodingA1: 7585bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 75866bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice d = Bits32 (opcode, 15, 12); 75876bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice m = Bits32 (opcode, 3, 0); 75886bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 75896bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75906bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 75916bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice if ((d == 15) || (m == 15)) 75926bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 75936bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice break; 75956bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 75966bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice default: 75976bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 75986bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice } 75996bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 7600868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7601868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (!success) 7602868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 76036bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76046bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // rotated = ROR(R[m], rotation); 76056bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice uint64_t rotated = ROR (Rm, rotation); 76066bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76076bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // R[d] = SignExtend(rotated<7:0>, 32); 76088ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice int64_t data = llvm::SignExtend64<8>(rotated); 76096bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76106bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice Register source_reg; 76116bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 76126bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76136bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice EmulateInstruction::Context context; 76146bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice context.type = eContextRegisterLoad; 76156bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice context.SetRegister (source_reg); 76166bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 76178ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 76186bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return false; 76196bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice } 76206bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice return true; 76216bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice} 7622291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice 7623868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7624868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7625868198b229fcffbda2b24518007179ef1a45ad1dCaroline Ticebool 76267bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7627868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice{ 7628868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#if 0 7629868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if ConditionPassed() then 7630868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice EncodingSpecificOperations(); 7631868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotated = ROR(R[m], rotation); 7632868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice R[d] = SignExtend(rotated<15:0>, 32); 7633868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#endif 7634868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7635868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice bool success = false; 7636868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 76377bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7638868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 7639868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t d; 7640868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t m; 7641868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint32_t rotation; 7642868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7643868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // EncodingSpecificOperations(); 7644868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice switch (encoding) 7645868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 7646868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingT1: 7647868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7648868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 2, 0); 7649868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 5, 3); 7650868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = 0; 7651868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7652868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7653868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7654868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingT2: 7655bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7656868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 11, 8); 7657868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 3, 0); 7658868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 7659868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7660868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7661868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (BadReg (d) || BadReg (m)) 7662868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7663868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7664868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7665868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7666868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice case eEncodingA1: 7667bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7668868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice d = Bits32 (opcode, 15, 12); 7669868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice m = Bits32 (opcode, 3, 0); 7670868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 7671868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7672868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 7673868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if ((d == 15) || (m == 15)) 7674868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7675868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7676868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice break; 7677868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7678868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice default: 7679868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7680868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice } 7681868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7682868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7683868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice if (!success) 7684868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7685868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7686868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // rotated = ROR(R[m], rotation); 7687868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice uint64_t rotated = ROR (Rm, rotation); 7688868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7689868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice // R[d] = SignExtend(rotated<15:0>, 32); 7690868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice Register source_reg; 7691868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 7692868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7693868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice EmulateInstruction::Context context; 7694868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice context.type = eContextRegisterLoad; 7695868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice context.SetRegister (source_reg); 7696868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 76978ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice int64_t data = llvm::SignExtend64<16> (rotated); 76988ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7699868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return false; 7700868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice } 7701868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 7702868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice return true; 7703868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice} 7704868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice 77058ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 77068ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 77078ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Ticebool 77087bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 77098ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice{ 77108ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#if 0 77118ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if ConditionPassed() then 77128ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice EncodingSpecificOperations(); 77138ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotated = ROR(R[m], rotation); 77148ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice R[d] = ZeroExtend(rotated<7:0>, 32); 77158ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#endif 77168ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77178ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice bool success = false; 77188ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77197bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 77208ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 77218ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t d; 77228ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t m; 77238ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint32_t rotation; 77248ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77258ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // EncodingSpecificOperations(); 77268ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice switch (encoding) 77278ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 77288ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingT1: 77298ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 77308ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 2, 0); 77318ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 5, 3); 77328ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = 0; 77338ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77348ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 77358ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77368ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingT2: 7737bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 77388ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 11, 8); 77398ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 3, 0); 77408ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 77418ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77428ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 77438ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (BadReg (d) || BadReg (m)) 77448ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77458ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77468ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 77478ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77488ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice case eEncodingA1: 7749bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 77508ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice d = Bits32 (opcode, 15, 12); 77518ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice m = Bits32 (opcode, 3, 0); 77528ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 77538ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77548ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 77558ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if ((d == 15) || (m == 15)) 77568ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77578ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77588ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice break; 77598ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77608ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice default: 77618ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77628ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice } 77638ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77648ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 77658ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!success) 77668ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77678ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77688ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // rotated = ROR(R[m], rotation); 77698ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice uint64_t rotated = ROR (Rm, rotation); 77708ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77718ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice // R[d] = ZeroExtend(rotated<7:0>, 32); 77728ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice Register source_reg; 77738ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 77748ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77758ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice EmulateInstruction::Context context; 77768ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice context.type = eContextRegisterLoad; 77778ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice context.SetRegister (source_reg); 77788ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 77798ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 77808ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return false; 77818ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice } 77828ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice return true; 77838ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice} 77848ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice 778511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 778611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 778711555f2f0f21beb0312f8ebe40849487d437f493Caroline Ticebool 77887bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 778911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice{ 779011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#if 0 779111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if ConditionPassed() then 779211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice EncodingSpecificOperations(); 779311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotated = ROR(R[m], rotation); 779411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice R[d] = ZeroExtend(rotated<15:0>, 32); 779511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#endif 779611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 779711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice bool success = false; 779811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 77997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 780011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 780111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t d; 780211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t m; 780311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint32_t rotation; 780411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 780511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice switch (encoding) 780611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 780711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingT1: 780811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = 0; 780911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 2, 0); 781011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 5, 3); 781111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = 0; 781211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 781311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 781411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 781511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingT2: 7816bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 781711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 11, 8); 781811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 3, 0); 781911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = Bits32 (opcode, 5, 4) << 3; 782011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 782111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 782211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (BadReg (d) || BadReg (m)) 782311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 782411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 782511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 782611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 782711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice case eEncodingA1: 7828bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 782911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice d = Bits32 (opcode, 15, 12); 783011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice m = Bits32 (opcode, 3, 0); 783111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice rotation = Bits32 (opcode, 11, 10) << 3; 783211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 783311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // if d == 15 || m == 15 then UNPREDICTABLE; 783411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if ((d == 15) || (m == 15)) 783511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 783611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 783711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice break; 783811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 783911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice default: 784011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 784111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice } 784211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 784311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 784411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (!success) 784511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 784611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 784711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // rotated = ROR(R[m], rotation); 784811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice uint64_t rotated = ROR (Rm, rotation); 784911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 785011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice // R[d] = ZeroExtend(rotated<15:0>, 32); 785111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice Register source_reg; 785211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 785311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 785411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice EmulateInstruction::Context context; 785511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice context.type = eContextRegisterLoad; 785611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice context.SetRegister (source_reg); 785711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 785811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 785911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return false; 786011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice } 786111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice return true; 786211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice} 7863b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7864b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 7865b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// word respectively. 7866b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 78677bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 7868b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 7869b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#if 0 7870b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if ConditionPassed() then 7871b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice EncodingSpecificOperations(); 7872b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 7873b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice UNPREDICTABLE; 7874b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 7875b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = if increment then R[n] else R[n]-8; 7876b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if wordhigher then address = address+4; 7877bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 7878b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice BranchWritePC(MemA[address,4]); 7879b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if wback then R[n] = if increment then R[n]+8 else R[n]-8; 7880b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#endif 7881b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7882b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool success = false; 7883b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 78847bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 7885b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7886b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint32_t n; 7887b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool wback; 7888b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool increment; 7889b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool wordhigher; 7890b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7891b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // EncodingSpecificOperations(); 7892b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice switch (encoding) 7893b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7894b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingT1: 7895bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 7896b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 7897b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 7898b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = false; 7899b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = false; 7900b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7901b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 7902b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 7903b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7904b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7905b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 7906b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (InITBlock() && !LastInITBlock()) 7907b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7908b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7909b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 7910b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7911b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingT2: 7912bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 7913b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 7914b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 7915b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = true; 7916b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = false; 7917b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7918b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 7919b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 7920b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7921b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7922b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 7923b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (InITBlock() && !LastInITBlock()) 7924b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7925b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7926b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 7927b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7928b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case eEncodingA1: 7929b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // n = UInt(Rn); 7930b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice n = Bits32 (opcode, 19, 16); 7931b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7932bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 7933b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wback = BitIsSet (opcode, 21); 7934b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice increment = BitIsSet (opcode, 23); 7935b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 7936b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7937b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if n == 15 then UNPREDICTABLE; 7938b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (n == 15) 7939b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7940b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7941b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice break; 7942b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7943b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice default: 7944b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7945b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 7946b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7947b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 7948b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!CurrentModeIsPrivileged ()) 7949b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // UNPREDICTABLE; 7950b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7951b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 7952b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7953b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7954b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 7955b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7956b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7957b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice addr_t address; 7958b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // address = if increment then R[n] else R[n]-8; 7959b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (increment) 7960b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = Rn; 7961b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 7962b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = Rn - 8; 7963b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7964b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if wordhigher then address = address+4; 7965b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (wordhigher) 7966b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice address = address + 4; 7967b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7968bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 7969b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice Register base_reg; 7970b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 7971b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7972b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice EmulateInstruction::Context context; 7973b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.type = eContextReturnFromException; 7974b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetRegisterPlusOffset (base_reg, address - Rn); 7975b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7976b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t data = MemARead (context, address + 4, 4, 0, &success); 7977b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 7978b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7979b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7980b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice CPSRWriteByInstr (data, 15, true); 7981b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7982b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // BranchWritePC(MemA[address,4]); 7983b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint64_t data2 = MemARead (context, address, 4, 0, &success); 7984b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!success) 7985b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7986b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7987b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice BranchWritePC (context, data2); 7988b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 7989b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 7990b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (wback) 7991b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7992b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.type = eContextAdjustBaseRegister; 7993b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (increment) 7994b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 7995b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetOffset (8); 7996b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 7997b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 7998b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 7999b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice else 8000b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 8001b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice context.SetOffset (-8); 8002b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8003b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 8004b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8005b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } // if wback 8006b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 8007b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } // if ConditionPassed() 8008b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 8009b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 801011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice 80112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 80122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// and writes the result to the destination register. It can optionally update the condition flags based on 80132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 80142115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 80157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 80162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 80172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 80182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 80192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 80202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 80212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 80222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 80232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 80242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 80252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 80262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 80272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 80282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 80292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 80302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 80312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 80322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 80342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80357bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 80362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 80372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn; 80382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 80392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 80402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 80412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 80422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 80432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 80442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 80452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 80462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 80472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 80482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 80492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 80507bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTEQImm (opcode, eEncodingT1); 80512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 80522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 80542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 80552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 80562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 80572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 80582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 80592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 80602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 80612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 80622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 80642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 80652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 80672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 80692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 80702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 80712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 80742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 80762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 80772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 80782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 80802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 80812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 80822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 80832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 80842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 80852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 80862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value, and writes the result to the destination register. 80872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// It can optionally update the condition flags based on the result. 80882115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 80897bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 80902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 80912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 80922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 80932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 80942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 80952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 80962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 80972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if d == 15 then // Can only occur for ARM encoding 80982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ALUWritePC(result); // setflags is always FALSE here 80992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen else 81002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen R[d] = result; 81012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if setflags then 81022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 81032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 81042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 81052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 81062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 81072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 81092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 81112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 81122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rd, Rn, Rm; 81132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 81142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 81152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool setflags; 81162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 81172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 81182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 81192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 81202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Rn = Bits32(opcode, 2, 0); 81212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 5, 3); 81222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = !InITBlock(); 81232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_t = SRType_LSL; 81242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen shift_n = 0; 8125ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 81262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT2: 81272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 11, 8); 81282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 81292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 81302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 81313dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 81323dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen // if Rd == '1111' && S == '1' then SEE TEQ (register); 81332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 81347bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateTEQReg (opcode, eEncodingT1); 81352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 81362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 81382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 81392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rd = Bits32(opcode, 15, 12); 81402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 81412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 81422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen setflags = BitIsSet(opcode, 20); 81433dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 81442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 81452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 81462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (Rd == 15 && setflags) 81472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 81492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 81502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 81522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 81542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 81552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 81562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 81592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 81602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 81612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 81642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 81652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 81672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 81682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 81692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 81712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 81722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 81732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 81742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 81752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 81767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 81777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// writes the result to the destination register. It can optionally update the condition flags based 81787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 81797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 81807bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 81817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 81827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 81837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 81847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 81857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 81867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR imm32; 81877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 81887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 81897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 81907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 81917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 81927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 81937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 81947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 81957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 81967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 81977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 81987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 81997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 82017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn; 82037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 82047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 82057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 82067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 82077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 82097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 82107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 82117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 82127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8213bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' then SEE MOV (immediate); 82147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 82157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdImm (opcode, eEncodingT2); 82167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13) 82177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 82197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 82207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 82217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 82227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 82237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 82247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 82257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 82267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 82287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 82297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 82317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 82337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 82347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 82357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t result = val1 | imm32; 82387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 82407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 82417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 82427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 82447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 82457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 82467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 82477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 82487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 82507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// value, and writes the result to the destination register. It can optionally update the condition flags based 82517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result. 82527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool 82537bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 82547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{ 82557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0 82567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // ARM pseudo code... 82577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if ConditionPassed() then 82587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EncodingSpecificOperations(); 82597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 82607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen result = R[n] OR shifted; 82617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if d == 15 then // Can only occur for ARM encoding 82627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ALUWritePC(result); // setflags is always FALSE here 82637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen else 82647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen R[d] = result; 82657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if setflags then 82667c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.N = result<31>; 82677c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.Z = IsZeroBit(result); 82687c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen APSR.C = carry; 82697c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // APSR.V unchanged 82707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif 82717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool success = false; 82737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 82747bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 82757c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t Rd, Rn, Rm; 82777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen ARM_ShifterType shift_t; 82787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 82797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen bool setflags; 82807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t carry; 82817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen switch (encoding) 82827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 82837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT1: 82847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 82857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 5, 3); 82867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = !InITBlock(); 82877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_t = SRType_LSL; 82887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen shift_n = 0; 8289ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 82907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingT2: 82917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 11, 8); 82927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 82937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 82947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 82953dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 82963dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen // if Rn == '1111' then SEE MOV (register); 82977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rn == 15) 82987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateMOVRdRm (opcode, eEncodingT3); 82997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 83007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 83027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen case eEncodingA1: 83037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rd = Bits32(opcode, 15, 12); 83047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rn = Bits32(opcode, 19, 16); 83057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen Rm = Bits32(opcode, 3, 0); 83067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen setflags = BitIsSet(opcode, 20); 83073dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 83087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 83097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (Rd == 15 && setflags) 83107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen break; 83127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen default: 83137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 83157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the first operand. 83177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 83187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 83197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // Read the second operand. 83227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 83237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!success) 83247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 83272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 | shifted; 83287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen EmulateInstruction::Context context; 83307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.type = EmulateInstruction::eContextImmediate; 83317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen context.SetNoArgs (); 83327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 83337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 83347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return false; 83357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen } 83367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen return true; 83377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen} 83387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 8339ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8340ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// the destination register. It can optionally update the condition flags based on the result. 8341ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool 83427bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8343ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{ 8344ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0 8345ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // ARM pseudo code... 8346ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if ConditionPassed() then 8347ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EncodingSpecificOperations(); 8348ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8349ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if d == 15 then // Can only occur for ARM encoding 8350ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ALUWritePC(result); // setflags is always FALSE here 8351ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen else 8352ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen R[d] = result; 8353ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if setflags then 8354ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.N = result<31>; 8355ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.Z = IsZeroBit(result); 8356ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.C = carry; 8357ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.V = overflow; 8358ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif 8359ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8360ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool success = false; 8361ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8362ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rd; // the destination register 8363ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rn; // the first operand 8364ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool setflags; 8365ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8366ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen switch (encoding) { 8367ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT1: 8368ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 2, 0); 8369ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 5, 3); 8370ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = !InITBlock(); 8371ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = 0; 8372ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8373ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT2: 8374ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 11, 8); 8375ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8376ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8377ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8378ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 8379ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8380ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8381ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingA1: 8382ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 15, 12); 8383ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8384ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8385ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8386ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8387ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 8388ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (Rd == 15 && setflags) 8389ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8390ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8391ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen default: 8392ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8393ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen } 8394ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from the operand register Rn. 8395ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 8396ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8397ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8398ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8399ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8400ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8401ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EmulateInstruction::Context context; 8402ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.type = EmulateInstruction::eContextImmediate; 8403ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.SetNoArgs (); 8404ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8405ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8406ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8407ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8408ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return true; 8409ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen} 8410ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8411ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8412ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// result to the destination register. It can optionally update the condition flags based on the result. 8413ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool 84147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8415ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{ 8416ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0 8417ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // ARM pseudo code... 8418ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if ConditionPassed() then 8419ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EncodingSpecificOperations(); 8420ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8421ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8422ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if d == 15 then // Can only occur for ARM encoding 8423ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ALUWritePC(result); // setflags is always FALSE here 8424ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen else 8425ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen R[d] = result; 8426ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if setflags then 8427ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.N = result<31>; 8428ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.Z = IsZeroBit(result); 8429ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.C = carry; 8430ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen APSR.V = overflow; 8431ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif 8432ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8433ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool success = false; 8434ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8435ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rd; // the destination register 8436ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rn; // the first operand 8437ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t Rm; // the second operand 8438ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen bool setflags; 8439ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen ARM_ShifterType shift_t; 8440ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 8441ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen switch (encoding) { 8442ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingT1: 8443ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 11, 8); 8444ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8445ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rm = Bits32(opcode, 3, 0); 8446ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8447ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 8448ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8449ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8450ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8451ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8452ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen case eEncodingA1: 8453ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rd = Bits32(opcode, 15, 12); 8454ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rn = Bits32(opcode, 19, 16); 8455ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen Rm = Bits32(opcode, 3, 0); 8456ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen setflags = BitIsSet(opcode, 20); 8457ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 8458ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8459ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 8460ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (Rd == 15 && setflags) 8461ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8462ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 8463ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen default: 8464ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8465ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen } 8466ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from register Rn. 8467ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 8468ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8469ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8470ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8471ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // Read the register value from register Rm. 8472ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 8473ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!success) 8474ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8475ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8476ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 8477ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8478ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8479ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen EmulateInstruction::Context context; 8480ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.type = EmulateInstruction::eContextImmediate; 8481ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen context.SetNoArgs(); 8482ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8483ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return false; 8484ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 8485ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen return true; 8486ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen} 8487ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen 848890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 848990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// an immediate value, and writes the result to the destination register. It can optionally update the condition 849090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// flags based on the result. 849190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool 84927bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 849390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{ 849490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0 849590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // ARM pseudo code... 849690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if ConditionPassed() then 849790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EncodingSpecificOperations(); 849890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 849990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if d == 15 then 850090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ALUWritePC(result); // setflags is always FALSE here 850190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen else 850290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen R[d] = result; 850390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if setflags then 850490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.N = result<31>; 850590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.Z = IsZeroBit(result); 850690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.C = carry; 850790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.V = overflow; 850890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif 850990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 851090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool success = false; 851190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 851290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rd; // the destination register 851390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rn; // the first operand 851490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool setflags; 851590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 851690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen switch (encoding) { 851790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen case eEncodingA1: 851890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rd = Bits32(opcode, 15, 12); 851990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rn = Bits32(opcode, 19, 16); 852090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen setflags = BitIsSet(opcode, 20); 852190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 852290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 852390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 852490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (Rd == 15 && setflags) 852590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 852690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen break; 852790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen default: 852890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 852990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen } 853090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from the operand register Rn. 853190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 853290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 853390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 853490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 853590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 853690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 853790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EmulateInstruction::Context context; 853890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.type = EmulateInstruction::eContextImmediate; 853990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.SetNoArgs (); 854090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 854190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 854290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 854390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 854490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return true; 854590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen} 854690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 854790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 854890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 854990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// condition flags based on the result. 855090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool 85517bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 855290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{ 855390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0 855490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // ARM pseudo code... 855590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if ConditionPassed() then 855690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EncodingSpecificOperations(); 855790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 855890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 855990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if d == 15 then 856090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ALUWritePC(result); // setflags is always FALSE here 856190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen else 856290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen R[d] = result; 856390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if setflags then 856490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.N = result<31>; 856590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.Z = IsZeroBit(result); 856690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.C = carry; 856790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen APSR.V = overflow; 856890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif 856990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 857090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool success = false; 857190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 857290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rd; // the destination register 857390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rn; // the first operand 857490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t Rm; // the second operand 857590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen bool setflags; 857690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen ARM_ShifterType shift_t; 857790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 857890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen switch (encoding) { 857990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen case eEncodingA1: 858090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rd = Bits32(opcode, 15, 12); 858190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rn = Bits32(opcode, 19, 16); 858290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen Rm = Bits32(opcode, 3, 0); 858390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen setflags = BitIsSet(opcode, 20); 858490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 858590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 858690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 858790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (Rd == 15 && setflags) 858890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 858990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen break; 859090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen default: 859190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 859290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen } 859390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from register Rn. 859490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 859590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 859690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 859790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 859890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // Read the register value from register Rm. 859990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 860090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!success) 860190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 860290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 860390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 860490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 860590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 860690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen EmulateInstruction::Context context; 860790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.type = EmulateInstruction::eContextImmediate; 860890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen context.SetNoArgs(); 860990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 861090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return false; 861190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 861290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen return true; 861390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen} 861490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen 86159b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (immediate) subtracts an immediate value and the value of 86169b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register. 86179b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result. 86189b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool 86197bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 86209b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{ 86219b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0 86229b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // ARM pseudo code... 86239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if ConditionPassed() then 86249b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EncodingSpecificOperations(); 862515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 86269b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if d == 15 then // Can only occur for ARM encoding 86279b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 86289b381775c532270fd07a90aa1a98750546a768b7Johnny Chen else 86299b381775c532270fd07a90aa1a98750546a768b7Johnny Chen R[d] = result; 86309b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if setflags then 86319b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.N = result<31>; 86329b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.Z = IsZeroBit(result); 86339b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.C = carry; 86349b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.V = overflow; 86359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif 86369b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool success = false; 86389b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86399b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rd; // the destination register 86409b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rn; // the first operand 86419b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool setflags; 86429b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t imm32; // the immediate value to be added to the value obtained from Rn 86439b381775c532270fd07a90aa1a98750546a768b7Johnny Chen switch (encoding) { 86449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT1: 86459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 11, 8); 86469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 86479b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 86489b381775c532270fd07a90aa1a98750546a768b7Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 86499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (BadReg(Rd) || BadReg(Rn)) 86509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 86529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingA1: 86539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 15, 12); 86549b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 86559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 86569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 86579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 86589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 86599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (Rd == 15 && setflags) 86609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 86629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen default: 86639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen } 86659b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from the operand register Rn. 86669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 86679b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 86689b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86699b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86709b381775c532270fd07a90aa1a98750546a768b7Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 86719b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86729b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EmulateInstruction::Context context; 86739b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 86749b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.SetNoArgs (); 86759b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86769b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 86779b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 86789b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86799b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return true; 86809b381775c532270fd07a90aa1a98750546a768b7Johnny Chen} 86819b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 86829b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 86839b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register. 86849b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result. 86859b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool 86867bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 86879b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{ 86889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0 86899b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // ARM pseudo code... 86909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if ConditionPassed() then 86919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EncodingSpecificOperations(); 86929b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shifted = Shift(R[m], shift_t, shift_n, APSR.C); 86939b381775c532270fd07a90aa1a98750546a768b7Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 86949b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if d == 15 then // Can only occur for ARM encoding 86959b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ALUWritePC(result); // setflags is always FALSE here 86969b381775c532270fd07a90aa1a98750546a768b7Johnny Chen else 86979b381775c532270fd07a90aa1a98750546a768b7Johnny Chen R[d] = result; 86989b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if setflags then 86999b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.N = result<31>; 87009b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.Z = IsZeroBit(result); 87019b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.C = carry; 87029b381775c532270fd07a90aa1a98750546a768b7Johnny Chen APSR.V = overflow; 87039b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif 87049b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87059b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool success = false; 87069b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87079b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rd; // the destination register 87089b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rn; // the first operand 87099b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t Rm; // the second operand 87109b381775c532270fd07a90aa1a98750546a768b7Johnny Chen bool setflags; 87119b381775c532270fd07a90aa1a98750546a768b7Johnny Chen ARM_ShifterType shift_t; 87129b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 87139b381775c532270fd07a90aa1a98750546a768b7Johnny Chen switch (encoding) { 87149b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT1: 87159b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Rn = Bits32(opcode, 2, 0); 87169b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 5, 3); 87179b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = !InITBlock(); 87189b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_t = SRType_LSL; 87199b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = 0; 87209b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 87219b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingT2: 87229b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 11, 8); 87239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 87249b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 3, 0); 87259b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 87269b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 87279b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 87289b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87299b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 87309b381775c532270fd07a90aa1a98750546a768b7Johnny Chen case eEncodingA1: 87319b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rd = Bits32(opcode, 15, 12); 87329b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rn = Bits32(opcode, 19, 16); 87339b381775c532270fd07a90aa1a98750546a768b7Johnny Chen Rm = Bits32(opcode, 3, 0); 87349b381775c532270fd07a90aa1a98750546a768b7Johnny Chen setflags = BitIsSet(opcode, 20); 87359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 87369b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 87379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 87389b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (Rd == 15 && setflags) 87399b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87409b381775c532270fd07a90aa1a98750546a768b7Johnny Chen break; 87419b381775c532270fd07a90aa1a98750546a768b7Johnny Chen default: 87429b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87439b381775c532270fd07a90aa1a98750546a768b7Johnny Chen } 87449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from register Rn. 87459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 87469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 87479b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87489b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // Read the register value from register Rm. 87509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 87519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!success) 87529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87549b381775c532270fd07a90aa1a98750546a768b7Johnny Chen uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 87559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 87569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen EmulateInstruction::Context context; 87589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.type = EmulateInstruction::eContextImmediate; 87599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen context.SetNoArgs(); 87609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 87619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return false; 87629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 87639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen return true; 87649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen} 87659b381775c532270fd07a90aa1a98750546a768b7Johnny Chen 876615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result 876715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register. It can optionally update the condition flags based on the result. 876815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool 87697bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 877015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{ 877115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0 877215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // ARM pseudo code... 877315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if ConditionPassed() then 877415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EncodingSpecificOperations(); 877515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 877615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen R[d] = result; 877715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if setflags then 877815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.N = result<31>; 877915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.Z = IsZeroBit(result); 878015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.C = carry; 878115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.V = overflow; 878215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif 878315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 878415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool success = false; 878515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 878615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rd; // the destination register 878715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rn; // the first operand 878815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool setflags; 878915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 879015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen switch (encoding) { 879115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT1: 879215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 2, 0); 879315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 5, 3); 879415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = !InITBlock(); 879515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 879615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 879715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT2: 879815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Rn = Bits32(opcode, 10, 8); 879915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = !InITBlock(); 880015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 880115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 880215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT3: 880315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 11, 8); 880415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 880515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 880615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 880715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 880815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE CMP (immediate); 880915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 88107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateCMPImm (opcode, eEncodingT2); 881115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 8812bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE SUB (SP minus immediate); 881315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 88147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingT2); 881515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 881615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 881715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 881815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 881915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 882015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingT4: 882115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 11, 8); 882215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 882315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 882415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 882515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 882615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rn == '1111' then SEE ADR; 882715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 15) 88287bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateADR (opcode, eEncodingT2); 882915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 883015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rn == '1101' then SEE SUB (SP minus immediate); 883115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 88327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingT3); 883315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 883415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (BadReg(Rd)) 883515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 883615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 883715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen default: 883815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 883915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen } 884015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // Read the register value from the operand register Rn. 884115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 884215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!success) 884315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 884415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 884515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 884615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 884715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EmulateInstruction::Context context; 884815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.type = EmulateInstruction::eContextImmediate; 884915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.SetNoArgs (); 885015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 885115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 885215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 885315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 885415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return true; 885515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen} 885615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 885715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result 885815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register. It can optionally update the condition flags based on the result. 885915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool 88607bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 886115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{ 886215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0 886315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // ARM pseudo code... 886415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if ConditionPassed() then 886515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EncodingSpecificOperations(); 886615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 886715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if d == 15 then 886815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen ALUWritePC(result); // setflags is always FALSE here 886915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen else 887015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen R[d] = result; 887115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if setflags then 887215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.N = result<31>; 887315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.Z = IsZeroBit(result); 887415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.C = carry; 887515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen APSR.V = overflow; 887615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif 887715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 887815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool success = false; 887915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 888015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rd; // the destination register 888115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t Rn; // the first operand 888215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen bool setflags; 888315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 888415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen switch (encoding) { 888515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen case eEncodingA1: 888615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rd = Bits32(opcode, 15, 12); 888715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen Rn = Bits32(opcode, 19, 16); 888815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen setflags = BitIsSet(opcode, 20); 888915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 889015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 8891bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1111' && S == '0' then SEE ADR; 889215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 15 && !setflags) 88937bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateADR (opcode, eEncodingA2); 889415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 8895bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice // if Rn == '1101' then SEE SUB (SP minus immediate); 889615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rn == 13) 88977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return EmulateSUBSPImm (opcode, eEncodingA1); 889815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 889915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 890015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // TODO: Emulate SUBS PC, LR and related instructions. 890115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (Rd == 15 && setflags) 890215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 890315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen break; 890415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen default: 890515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 890615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen } 890715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // Read the register value from the operand register Rn. 890815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen uint32_t reg_val = ReadCoreReg(Rn, &success); 890915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!success) 891015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 891115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 891215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 891315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 891415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen EmulateInstruction::Context context; 891515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.type = EmulateInstruction::eContextImmediate; 891615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen context.SetNoArgs (); 891715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 891815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 891915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return false; 892015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 892115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen return true; 892215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen} 892315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen 89242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 89252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// immediate value. It updates the condition flags based on the result, and discards the result. 89262115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 89277bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 89282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 89292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 89302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 89312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 89322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 89332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR imm32; 89342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 89352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 89362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 89372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 89382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 89392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 89412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89427bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 89432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 89442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn; 89452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 89462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 89472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 89482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 89492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 89502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 89517bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 89522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn)) 89532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 89552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 89562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 89577bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 89582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 89592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 89602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 89622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 89642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 89652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 89662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ imm32; 89692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 89712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 89722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 89732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 89752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 89762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 89772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 89782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 89792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 89812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value. It updates the condition flags based on the result, and discards 89822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result. 89832115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool 89847bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 89852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{ 89862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0 89872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // ARM pseudo code... 89882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if ConditionPassed() then 89892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EncodingSpecificOperations(); 89902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 89912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen result = R[n] EOR shifted; 89922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.N = result<31>; 89932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.Z = IsZeroBit(result); 89942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen APSR.C = carry; 89952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // APSR.V unchanged 89962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif 89972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 89982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen bool success = false; 89992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 90012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 90022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t Rn, Rm; 90032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen ARM_ShifterType shift_t; 90042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 90052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t carry; 90062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen switch (encoding) 90072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 90082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingT1: 90092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 90102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 90113dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 90122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (BadReg(Rn) || BadReg(Rm)) 90132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 90152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen case eEncodingA1: 90162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rn = Bits32(opcode, 19, 16); 90172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen Rm = Bits32(opcode, 3, 0); 90183dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 90192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen break; 90202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen default: 90212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 90232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the first operand. 90252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 90262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 90272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // Read the second operand. 90302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 90312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!success) 90322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 90352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen uint32_t result = val1 ^ shifted; 90362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen EmulateInstruction::Context context; 90382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.type = EmulateInstruction::eContextImmediate; 90392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen context.SetNoArgs (); 90402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 90412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen if (!WriteFlags(context, result, carry)) 90422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return false; 90432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen } 90442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen return true; 90452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen} 90462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen 9047de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9048de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 9049de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 90507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9051de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 9052de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 9053de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 9054de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 9055de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 9056de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND imm32; 9057de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 9058de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 9059de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 9060de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 9061de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 9062de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9063de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 9064de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 90657bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9066de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9067de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn; 9068de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9069de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9070de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 9071de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9072de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 9073de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9074de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9075de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn)) 9076de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9077de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9078de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 9079de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9080de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9081de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9082de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 9083de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9084de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9085de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9086de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 9087de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 9088de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9089de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9090de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9091de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & imm32; 9092de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9093de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 9094de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 9095de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 9096de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9097de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 9098de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9099de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9100de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 9101de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 9102de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9103de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9104de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result. 9105de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool 91067bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9107de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{ 9108de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0 9109de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // ARM pseudo code... 9110de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if ConditionPassed() then 9111de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EncodingSpecificOperations(); 9112de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9113de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen result = R[n] AND shifted; 9114de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.N = result<31>; 9115de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.Z = IsZeroBit(result); 9116de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen APSR.C = carry; 9117de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // APSR.V unchanged 9118de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif 9119de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9120de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen bool success = false; 9121de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 91227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (ConditionPassed(opcode)) 9123de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9124de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t Rn, Rm; 9125de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen ARM_ShifterType shift_t; 9126de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shift_n; // the shift applied to the value read from Rm 9127de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t carry; 9128de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen switch (encoding) 9129de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 9130de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT1: 9131de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 2, 0); 9132de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 5, 3); 9133de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_t = SRType_LSL; 9134de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen shift_n = 0; 9135ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen break; 9136de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingT2: 9137de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9138de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 91393dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftThumb(opcode, shift_t); 9140de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (BadReg(Rn) || BadReg(Rm)) 9141de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9142de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9143de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen case eEncodingA1: 9144de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rn = Bits32(opcode, 19, 16); 9145de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen Rm = Bits32(opcode, 3, 0); 91463dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen shift_n = DecodeImmShiftARM(opcode, shift_t); 9147de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen break; 9148de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen default: 9149de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9150de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9151de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9152de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the first operand. 9153de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val1 = ReadCoreReg(Rn, &success); 9154de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9155de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9156de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9157de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // Read the second operand. 9158de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t val2 = ReadCoreReg(Rm, &success); 9159de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!success) 9160de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9161de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9162de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 9163de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen uint32_t result = val1 & shifted; 9164de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9165de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen EmulateInstruction::Context context; 9166de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.type = EmulateInstruction::eContextImmediate; 9167de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen context.SetNoArgs (); 9168de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 9169de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen if (!WriteFlags(context, result, carry)) 9170de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return false; 9171de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen } 9172de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen return true; 9173de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen} 9174d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9175d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.216 SUB (SP minus register) 9176d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9177d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9178d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9179d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9180d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ConditionPassed() then 9181d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice EncodingSpecificOperations(); 9182d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9183d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’); 9184d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if d == 15 then // Can only occur for ARM encoding 9185d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice ALUWritePC(result); // setflags is always FALSE here 9186d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice else 9187d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice R[d] = result; 9188d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if setflags then 9189d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.N = result<31>; 9190d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.Z = IsZeroBit(result); 9191d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.C = carry; 9192d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice APSR.V = overflow; 9193d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9194d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9195d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice bool success = false; 9196d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9197d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9198d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9199d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t d; 9200d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t m; 9201d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice bool setflags; 9202d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice ARM_ShifterType shift_t; 9203d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t shift_n; 9204d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9205d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9206d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9207d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice case eEncodingT1: 9208d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); 9209d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice d = Bits32 (opcode, 11, 8); 9210d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice m = Bits32 (opcode, 3, 0); 9211d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice setflags = BitIsSet (opcode, 20); 9212d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9213d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9214d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shift_n = DecodeImmShiftThumb (opcode, shift_t); 9215d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9216d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9217d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9218d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9219d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9220d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if d == 15 || BadReg(m) then UNPREDICTABLE; 9221d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if ((d == 15) || BadReg (m)) 9222d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9223d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice break; 9224d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9225d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice case eEncodingA1: 9226d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 9227d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); 9228d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice d = Bits32 (opcode, 15, 12); 9229d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice m = Bits32 (opcode, 3, 0); 9230d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice setflags = BitIsSet (opcode, 20); 9231d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9232d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9233d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice shift_n = DecodeImmShiftARM (opcode, shift_t); 9234d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice break; 9235d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9236d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice default: 9237d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9238d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9239d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9240d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9241d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t Rm = ReadCoreReg (m, &success); 9242d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!success) 9243d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9244d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9245d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); 9246d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9247d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’); 9248d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9249d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!success) 9250d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9251d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9252d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9253d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9254d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice EmulateInstruction::Context context; 9255d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice context.type = eContextSubtraction; 9256d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice Register sp_reg; 9257d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); 9258d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice Register dwarf_reg; 9259d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 9260d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9261d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9262d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice uint32_t regnum = dwarf_r0 + d; 9263d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9264d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (!WriteCoreRegOptionalFlags(context, res.result, regnum, setflags, res.carry_out, res.overflow)) 9265d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return false; 9266d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9267d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9268d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9269d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9270d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9271d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.7 ADD (register-shifted register) 9272d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9273d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateAddRegShift (const uint32_t opcode, const ARMEncoding encoding) 9274d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9275d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9276d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9277d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9278d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9279d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9280d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9281d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9282d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9283d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9284d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9285d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9286d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9287d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9288d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9289d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.213 SUB (register) 9290d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9291d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9292d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9293d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9294d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9295d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9296d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9297d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9298d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9299d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9300d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9301d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9302d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9303d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9304d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9305d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9306d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9307d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.202 STREX 9308d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9309d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9310d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9311d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9312d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9313d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9314d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9315d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9316d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9317d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9318d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9319d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9320d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9321d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9322d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9323d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9324d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9325d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.197 STRB (immediate, ARM) 9326d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9327d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9328d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9329d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9330d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9331d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9332d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9333d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9334d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9335d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9336d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9337d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9338d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9339d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9340d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9341d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9342d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9343d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.194 STR (immediate, ARM) 9344d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9345d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9346d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9347d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9348d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9349d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9350d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9351d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9352d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9353d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9354d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9355d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9356d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9357d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9358d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9359d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9360d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9361d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.74 LDRH (immediate, ARM) 9362d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9363d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRHImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 9364d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9365d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9366d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9367d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9368d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9369d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9370d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9371d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9372d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9373d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9374d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9375d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9376d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9377d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9378d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9379d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.69 LDREX 9380d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9381d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDREX (const uint32_t opcode, const ARMEncoding encoding) 9382d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9383d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9384d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9385d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9386d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9387d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9388d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9389d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9390d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9391d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9392d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9393d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9394d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9395d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9396d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9397d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.62 LDRB (immediate, ARM) 9398d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9399d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRBImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 9400d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9401d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9402d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9403d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9404d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9405d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9406d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9407d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9408d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9409d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9410d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9411d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9412d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9413d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9414d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9415d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.59 LDR (literal) 9416d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9417d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRLiteral (const uint32_t opcode, const ARMEncoding encoding) 9418d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9419d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9420d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9421d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9422d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9423d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9424d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9425d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9426d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9427d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9428d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9429d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9430d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9431d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9432d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9433d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9434d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9435d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.65 LDRBT 9436d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9437d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRBT (const uint32_t opcode, const ARMEncoding encoding) 9438d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9439d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9440d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9441d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9442d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9443d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9444d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9445d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9446d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9447d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9448d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9449d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9450d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9451d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9452d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9453d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9454d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.66 LDRD (immediate) 9455d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9456d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 9457d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9458d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9459d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9460d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9461d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9462d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9463d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9464d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9465d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9466d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9467d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9468d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9469d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9470d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9471d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9472d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9473d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.67 LDRD (literal) 9474d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9475d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDLiteral (const uint32_t opcode, const ARMEncoding encoding) 9476d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9477d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9478d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9479d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9480d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9481d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9482d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9483d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9484d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9485d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9486d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9487d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9488d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9489d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9490d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9491d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9492d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.68 LDRD (register) 9493d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9494d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 9495d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9496d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9497d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9498d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9499d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9500d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9501d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9502d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9503d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9504d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9505d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9506d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9507d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9508d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9509d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9510d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9511d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.70 LDREXB 9512d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9513d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDREXB (const uint32_t opcode, const ARMEncoding encoding) 9514d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9515d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9516d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9517d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9518d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9519d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9520d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9521d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9522d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9523d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9524d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9525d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9526d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9527d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9528d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9529d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9530d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.71 LDREXD 9531d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9532d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDREXD (const uint32_t opcode, const ARMEncoding encoding) 9533d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9534d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9535d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9536d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9537d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9538d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9539d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9540d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9541d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9542d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9543d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9544d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9545d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9546d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9547d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9548d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9549d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.72 LDREXH 9550d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9551d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDREXH (const uint32_t opcode, const ARMEncoding encoding) 9552d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9553d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9554d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9555d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9556d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9557d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9558d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9559d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9560d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9561d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9562d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9563d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9564d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9565d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9566d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9567d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9568d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9569d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.77 LDRHT 9570d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9571d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRHT (const uint32_t opcode, const ARMEncoding encoding) 9572d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9573d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9574d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9575d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9576d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9577d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9578d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9579d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9580d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9581d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9582d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9583d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9584d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9585d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9586d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9587d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9588d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.81 LDRSBT 9589d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9590d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRSBT (const uint32_t opcode, const ARMEncoding encoding) 9591d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9592d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9593d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9594d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9595d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9596d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9597d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9598d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9599d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9600d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9601d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9602d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9603d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9604d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9605d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9606d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9607d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.85 LDRSHT 9608d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9609d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRSHT (const uint32_t opcode, const ARMEncoding encoding) 9610d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9611d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9612d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9613d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9614d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9615d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9616d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9617d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9618d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9619d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9620d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9621d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9622d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9623d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9624d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9625d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9626d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.86 LDRT 9627d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9628d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRT (const uint32_t opcode, const ARMEncoding encoding) 9629d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9630d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9631d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9632d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9633d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9634d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9635d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9636d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9637d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9638d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9639d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9640d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9641d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9642d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9643d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9644d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9645d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9646d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.198 STRB (register) 9647d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9648d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRBReg (const uint32_t opcode, const ARMEncoding encoding) 9649d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9650d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9651d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9652d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9653d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9654d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9655d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9656d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9657d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9658d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9659d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9660d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9661d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9662d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9663d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9664d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9665d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.199 STRBT 9666d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9667d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRBT (const uint32_t opcode, const ARMEncoding encoding) 9668d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9669d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9670d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9671d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9672d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9673d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9674d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9675d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9676d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9677d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9678d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9679d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9680d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9681d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9682d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9683d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9684d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.200 STRD (immediate) 9685d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9686d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 9687d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9688d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9689d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9690d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9691d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9692d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9693d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9694d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9695d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9696d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9697d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9698d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9699d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9700d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9701d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9702d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9703d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.201 STRD (register) 9704d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9705d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 9706d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9707d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9708d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9709d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9710d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9711d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9712d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9713d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9714d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9715d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9716d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9717d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9718d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9719d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9720d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9721d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9722d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.203 STREXB 9723d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9724d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREXB (const uint32_t opcode, const ARMEncoding encoding) 9725d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9726d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9727d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9728d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9729d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9730d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9731d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9732d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9733d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9734d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9735d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9736d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9737d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9738d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9739d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9740d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9741d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.204 STREXD 9742d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9743d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREXD (const uint32_t opcode, const ARMEncoding encoding) 9744d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9745d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9746d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9747d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9748d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9749d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9750d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9751d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9752d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9753d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9754d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9755d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9756d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9757d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9758d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9759d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9760d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.205 STREXH 9761d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9762d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREXH (const uint32_t opcode, const ARMEncoding encoding) 9763d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9764d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9765d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9766d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9767d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9768d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9769d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9770d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9771d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9772d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9773d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9774d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9775d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9776d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9777d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9778d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9779d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.206 STRH (immediate, Thumb) 9780d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9781d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRHImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9782d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9783d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9784d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9785d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9786d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9787d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9788d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9789d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9790d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9791d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9792d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9793d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9794d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9795d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9796d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9797d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9798d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.207 STRH (immediate, ARM) 9799d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9800d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRHImmARM (const uint32_t opcode, const ARMEncoding encoding) 9801d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9802d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9803d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9804d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9805d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9806d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9807d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9808d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9809d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9810d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9811d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9812d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9813d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9814d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9815d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9816d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9817d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9818d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.209 STRHT 9819d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9820d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRHT (const uint32_t opcode, const ARMEncoding encoding) 9821d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9822d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9823d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9824d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9825d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice //bool success = false; 9826d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9827d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9828d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9829d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9830d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9831d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9832d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9833d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9834d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9835d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9836d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9837d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.210 STRT 9838d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool 9839d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRT (const uint32_t opcode, const ARMEncoding encoding) 9840d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{ 9841d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0 9842d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif 9843d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9844d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice // bool success = false; 9845d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9846d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice if (ConditionPassed(opcode)) 9847d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9848d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice switch (encoding) 9849d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 9850d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9851d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice } 9852d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice return true; 9853d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice} 9854d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9855d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9856d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice 9857de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 98582b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 98592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 986064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 98612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 98622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_arm_opcodes[] = 98632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 98642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 98652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 98662b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 98672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 98699f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 98709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 98712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 98739f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 9874864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 9875e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to ip 98769f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 98779f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 9878864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 98792b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 9881864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 9882d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 98832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push one register 98852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 98863e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 98872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 98899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 98909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 98912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 9893587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen // Epilogue instructions 98942b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 98952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 98969f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 98979f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 98989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 9899b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 9900b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 9901b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 9902b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 9903b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 99043b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 99053b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 99063b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 99073b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 99083b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 9909696b4effb53cac2ec14b54a65c695450b4d7f456Johnny Chen { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 9910383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // To resolve ambiguity, "blx <label>" should come before "bl <label>". 9911383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 9912383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 9913383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 9914ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 9915ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 991659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // bxj 991759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 9918b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 9919b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 992028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen // Data-processing instructions 992128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 9922157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 9923157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 9924157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 9925157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 99268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (immediate) 9927157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 99288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen // add (register) 9929157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 9930a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // adr 9931a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 9932a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 9933e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 9934157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 9935e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 9936157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 9937b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (immediate) 9938b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 9939b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (register) 9940b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 99412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 99422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 99432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 99442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 99457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 99467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 99477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 99487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 9949ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (immediate) 9950ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 9951ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (register) 9952ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 995390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // rsc (immediate) 995490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 995590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen // rsc (register) 995690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 99579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (immediate) 99589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 99599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (register) 99609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 996115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // sub (immediate, ARM) 996215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 9963c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen // sub (sp minus immediate) 9964c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 99652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 99662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 99672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 99682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 9969de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 9970de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 9971de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 9972de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 9973de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 997489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice // mov (immediate) 997589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 997689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 997701d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen // mov (register) 997801d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 9979d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 9980d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 9981d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 9982d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 99833847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (immediate) 99843847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 99853847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen // cmn (register) 99863847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 998734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 998834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 998934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) 999034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 999182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 999282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 99932ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // asr (register) 9994e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 99952ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 99962ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 99972ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 99982ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 99992ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 100002ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 100012ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 100022ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 10003eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 10004eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 10005eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 10006eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 10007eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 10008eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 100095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 100105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 1001128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen 1001228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen //---------------------------------------------------------------------- 10013b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 10014b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 100150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 10016713c2665a27096b68f3f8956222375354f1292f8Caroline Tice { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 1001785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 10018fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 100194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 10020fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 1002130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 100220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 10023952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 100240e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 10025a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 100265f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 10027672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 1002878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 10029291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 10030291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 10031fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 10032fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 10033fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 10034fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 100351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 10036b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 10037af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 100383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 100396bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 100408ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 100416bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 100426bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 100436bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // Other instructions 100446bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 10045868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 100468ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 1004711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 10048b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 10049b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 100501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice 100512b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 100522b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 100532b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100542b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_arm_opcodes; ++i) 100552b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 100562b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 100572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_arm_opcodes[i]; 100582b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 100592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 100602b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 100612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode* 100642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 10065347320d16d98cffaadf3f888569100c43b241068Johnny Chen{ 100662b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton static ARMOpcode 100682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton g_thumb_opcodes[] = 100692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 100702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 100712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Prologue instructions 100722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 100732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // push register(s) 100759f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 100769f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 100779f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 100782b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100792b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // set r7 to point to a stack offset 100809f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 10081e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // copy the stack pointer to r7 100829f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 10083e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 100849f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 100852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 10086864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen // PC-relative load into register (see also EmulateADDSPRm) 10087c9de910d61f0471d18fced716fc10681ef432010Johnny Chen { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 100882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // adjust the stack pointer 10090864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 10091c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 10092864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 10093864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 10094d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 100952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 100962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // vector push consecutive extension register(s) 10097d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 10098d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 100992b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 101002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 101012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton // Epilogue instructions 101022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton //---------------------------------------------------------------------- 101032b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 10104e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 10105864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 101069f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 101079f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 101089f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 10109d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 10110d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 10111b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 10112b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 10113b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen // Supervisor Call (previously Software Interrupt) 10114b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen //---------------------------------------------------------------------- 10115c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 10116c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 10117c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 10118c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // If Then makes up to four following instructions conditional. 10119c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen //---------------------------------------------------------------------- 101203b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 101213b620b38cd170c20ea607585021ab2ab50286943Johnny Chen 101223b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 101233b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // Branch instructions 101243b620b38cd170c20ea607585021ab2ab50286943Johnny Chen //---------------------------------------------------------------------- 101253b620b38cd170c20ea607585021ab2ab50286943Johnny Chen // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 101263b620b38cd170c20ea607585021ab2ab50286943Johnny Chen { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 10127e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 101289ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 10129696b4effb53cac2ec14b54a65c695450b4d7f456Johnny Chen { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 10130383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 10131e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 10132383d629938986b4ae4867f08505be8a9147c1308Johnny Chen // J1 == J2 == 1 10133e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 10134383d629938986b4ae4867f08505be8a9147c1308Johnny Chen { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 10135ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen // for example, "bx lr" 10136ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 1013759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen // bxj 1013859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 1013953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen // compare and branch 1014053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 1014160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch byte 1014260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 1014360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen // table branch halfword 1014460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 10145b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen 10146b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 1014726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Data-processing instructions 1014826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 10149157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (immediate) 10150157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 10151157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // adc (register) 10152157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 10153157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10154157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen // add (register) 101559f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 1015626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 101579f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 10158a695f958db37c102d480a9c0780abec262ba8332Johnny Chen // adr 10159a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 10160a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 10161a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 10162e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (immediate) 10163157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 10164e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen // and (register) 10165e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 10166e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10167b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (immediate) 10168b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 10169b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen // bic (register) 10170b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 10171b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 101722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (immediate) 101732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 101742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // eor (register) 101752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 101762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 101777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (immediate) 101787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 101797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // orr (register) 101807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 101817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10182ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (immediate) 10183ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 10184ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 10185ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen // rsb (register) 10186ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 101879b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (immediate) 101889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 101899b381775c532270fd07a90aa1a98750546a768b7Johnny Chen // sbc (register) 101909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 101919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 10192dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice // add (immediate, Thumb) 10193dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 10194dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 10195dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 10196dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 1019715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen // sub (immediate, Thumb) 1019815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 1019915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 1020015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 1020115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 10202c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen // sub (sp minus immediate) 10203c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 10204c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 102052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (immediate) 102062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 102072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen // teq (register) 102082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 10209de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (immediate) 102102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 10211de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen // tst (register) 10212de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 10213de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 10214de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen 102157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen 10216338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from high register to high register 102179f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 10218338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen // move from low register to low register 102199f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 102207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen // mov{s}<c>.w <Rd>, <Rm> 102217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 10222357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen // move immediate 102239f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 102249f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 1022589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 10226d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (immediate) 10227d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 10228d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen // mvn (register) 10229d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 10230d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 1023134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (immediate) 10232688926f8fb9a56964249ec970b4ae313a5b366d4Johnny Chen { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 1023334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmn (register) 1023434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 10235078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 1023634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (immediate) 1023734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 10238078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 1023934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm both from r0-r7) 1024034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 1024134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen // cmp (register) (Rn and Rm not both from r0-r7) 1024234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 1024382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen // asr (immediate) 1024482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 102454d896db529a5fef200333ef673976528319279bdJohnny Chen { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 10246e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen // asr (register) 10247e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 10248e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 102492ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (immediate) 102502ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 102512ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 102522ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsl (register) 102532ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 102542ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 102552ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (immediate) 102562ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 102572ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 102582ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen // lsr (register) 10259eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 102602ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 10261eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // rrx is a special case encoding of ror (immediate) 10262eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 10263eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (immediate) 10264eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 10265eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen // ror (register) 10266eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 10267eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 102685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 102695c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 102705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice // mul 102715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 102726bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 1027326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen //---------------------------------------------------------------------- 10274b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice // Load instructions 10275b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice //---------------------------------------------------------------------- 10276b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 102770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 10278ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 10279baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 10280baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 10281baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 10282baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 10283baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice // Thumb2 PC-relative load into register 10284fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 10285fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 10286fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 1028721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 1028821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 1028921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[>Rn>, #+/-<imm8>]{!}" }, 10290f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 1029130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 1029230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, eSize32,&EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 102930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 102940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 102950491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 10296952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 102970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 102980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 10299a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 10300a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 103015f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 10302672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 10303672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 1030478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 1030578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 10306d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 10307291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 10308291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 10309fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice 10310fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 10311fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice // Store instructions 10312fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice //---------------------------------------------------------------------- 10313fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 10314b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 103157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 10316fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 10317fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 10318fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 10319fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 10320fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 10321fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 10322fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 10323fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 103246bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 103258ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 103268ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 103276bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 103286bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 103296bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice // Other instructions 103306bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice //---------------------------------------------------------------------- 103316bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 10332868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 10333868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 103348ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 103358ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 1033611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 1033711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 10338b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 10339b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xffd00000, 0xe8100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 10340b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 0xffd00000, 0xe9900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" } 103416bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice 103422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton }; 103432b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton 103442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 103452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton for (size_t i=0; i<k_num_thumb_opcodes; ++i) 103462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton { 103472b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 103482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return &g_thumb_opcodes[i]; 103492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton } 103502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton return NULL; 103512b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton} 1035264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1035331e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool 10354395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 1035531e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{ 1035631e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton m_arm_isa = 0; 10357940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton const char *arch_cstr = arch.GetArchitectureName (); 10358395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (arch_cstr) 10359395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton { 10360395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 10361395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 10362395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 10363395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 10364395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 10365395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 10366395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 10367395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 10368395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 10369395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 1037031e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton } 1037131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton return m_arm_isa != 0; 1037231e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton} 1037331e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 1037431e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton 1037564c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 1037664c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction () 1037764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 1037864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool success = false; 10379b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 1038064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1038164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 1038264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 1038364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1038464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 103859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice Context read_inst_context; 103869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.type = eContextReadOpcode; 103879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice read_inst_context.SetNoArgs (); 103889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice 10389b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_cpsr & MASK_CPSR_T) 1039064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10391b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeThumb; 10392cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 1039364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1039464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (success) 1039564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 103967bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 1039764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 103987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode16 (thumb_opcode); 1039964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1040064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 1040164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 104027bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 1040364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1040464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1040564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1040664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton else 1040764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10408b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeARM; 104097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 1041064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1041164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1041264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1041364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (!success) 1041464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10415b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_mode = eModeInvalid; 10416b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_pc = LLDB_INVALID_ADDRESS; 1041764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1041864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return success; 1041964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 1042064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 10421ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t 10422ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion () 10423ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10424ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return m_arm_isa; 10425ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10426ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 1042764c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 104287bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::ConditionPassed (const uint32_t opcode) 1042964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 10430b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_cpsr == 0) 1043164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1043264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 104337bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton const uint32_t cond = CurrentCond (opcode); 1043464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1043564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond == UINT32_MAX) 1043664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1043764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1043864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton bool result = false; 1043964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton switch (UnsignedBits(cond, 3, 1)) 1044064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10441b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 0: result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; break; 10442b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 1: result = (m_opcode_cpsr & MASK_CPSR_C) != 0; break; 10443b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 2: result = (m_opcode_cpsr & MASK_CPSR_N) != 0; break; 10444b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 3: result = (m_opcode_cpsr & MASK_CPSR_V) != 0; break; 10445b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton case 4: result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); break; 1044664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 5: 1044764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10448b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool n = (m_opcode_cpsr & MASK_CPSR_N); 10449b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool v = (m_opcode_cpsr & MASK_CPSR_V); 1045064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = n == v; 1045164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1045264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1045364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 6: 1045464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton { 10455b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool n = (m_opcode_cpsr & MASK_CPSR_N); 10456b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool v = (m_opcode_cpsr & MASK_CPSR_V); 10457b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 1045864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1045964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1046064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton case 7: 1046164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = true; 1046264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton break; 1046364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton } 1046464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 1046564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton if (cond & 1) 1046664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton result = !result; 1046764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return result; 1046864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 1046964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 104709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t 104717bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::CurrentCond (const uint32_t opcode) 104729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 10473b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton switch (m_opcode_mode) 104749ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 104759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen default: 104769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeInvalid: 104779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen break; 104789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 104799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeARM: 104807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return UnsignedBits(opcode, 31, 28); 104819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 104829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen case eModeThumb: 104839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 104849ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen // 'cond' field of the encoding. 104859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 104867bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton const uint32_t byte_size = m_opcode.GetByteSize(); 104877bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (byte_size == 2) 104887bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 104897bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 104907bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return Bits32(opcode, 11, 7); 104917bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 104927bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton else 104937bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 104947bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton assert (byte_size == 4); 104957bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton if (Bits32(opcode, 31, 27) == 0x1e && 104967bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 15, 14) == 0x02 && 104977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 12, 12) == 0x00 && 104987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton Bits32(opcode, 25, 22) <= 0x0d) 104997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton { 105007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return Bits32(opcode, 25, 22); 105017bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 105027bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton } 105037bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton 105047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton return m_it_session.GetCond(); 105059ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 105069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 105079ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return UINT32_MAX; // Return invalid value 105089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 105099ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 105109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 10511098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock() 10512098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 10513098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 10514098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 10515098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 10516098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 10517098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock() 10518098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{ 10519098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 10520098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen} 10521098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen 10522b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 10523b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::BadMode (uint32_t mode) 10524b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 10525b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10526b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice switch (mode) 10527b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10528b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 16: return false; // '10000' 10529b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 17: return false; // '10001' 10530b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 18: return false; // '10010' 10531b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 19: return false; // '10011' 10532b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 22: return false; // '10110' 10533b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 23: return false; // '10111' 10534b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 27: return false; // '11011' 10535b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice case 31: return false; // '11111' 10536b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice default: return true; 10537b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10538b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 10539b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 10540b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10541b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool 10542b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CurrentModeIsPrivileged () 10543b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 10544b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 10545b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10546b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BadMode (mode)) 10547b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 10548b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10549b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (mode == 16) 10550b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return false; 10551b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10552b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice return true; 10553b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 10554b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10555b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticevoid 10556b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 10557b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{ 10558b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice bool privileged = CurrentModeIsPrivileged(); 10559b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10560b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice uint32_t tmp_cpsr = 0; 10561b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10562b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton tmp_cpsr = tmp_cpsr | (Bits32 (m_opcode_cpsr, 23, 20) << 20); 10563b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10564b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 3)) 10565b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10566b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 10567b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 10568b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 10569b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10570b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10571b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 2)) 10572b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10573b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 10574b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10575b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10576b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 1)) 10577b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10578b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 10579b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 10580b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 10581b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 10582b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 10583b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10584b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10585b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (BitIsSet (bytemask, 0)) 10586b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice { 10587b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 10588b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 10589b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (affect_execstate) 10590b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 10591b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice if (privileged) 10592b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 10593b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice } 10594b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10595b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_opcode_cpsr = tmp_cpsr; 10596b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice} 10597b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10598b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice 10599098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool 106009ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 106019ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 106029ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 106039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 10604ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Check the current instruction set. 10605ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (CurrentInstrSet() == eModeARM) 106069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 10607ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 106089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 10609ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 106109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1061153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 1061253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 1061353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 106149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 106159ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 106169ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 106179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool 10618668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 106199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{ 106209ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen addr_t target; 106210f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 106220f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // we want to record it and issue a WriteRegister callback so the clients 106230f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen // can track the mode changes accordingly. 106240f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen bool cpsr_changed = false; 106259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 106269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (BitIsSet(addr, 0)) 106279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 106280f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeThumb) 106290f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 106300f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeThumb); 106310f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 106320f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 106339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffe; 10634668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetMode (eModeThumb); 106359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 106369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else if (BitIsClear(addr, 1)) 106379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen { 106380f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (CurrentInstrSet() != eModeARM) 106390f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 106400f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen SelectInstrSet(eModeARM); 106410f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen cpsr_changed = true; 106420f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 106439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen target = addr & 0xfffffffc; 10644668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen context.SetMode (eModeARM); 106459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen } 106469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen else 106479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen return false; // address<1:0> == '10' => UNPREDICTABLE 106489ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen 106490f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen if (cpsr_changed) 106500f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen { 10651558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 106520f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen return false; 106530f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen } 106549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1065553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return false; 1065653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen 1065753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen return true; 106589ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen} 1065964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton 10660ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 10661ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 10662668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 10663ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10664ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen if (ArchVersion() >= ARMv5T) 10665668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 10666ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen else 10667ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return BranchWritePC((const Context)context, addr); 10668ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10669ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 1067026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 1067126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool 10672668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 1067326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{ 1067426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 10675668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen return BXWritePC(context, addr); 1067626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen else 1067726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen return BranchWritePC((const Context)context, addr); 1067826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen} 1067926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen 10680ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode 10681ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet () 10682ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10683b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton return m_opcode_mode; 10684ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10685ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 10686b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 10687558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed. This function has a side effect of updating 10688558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary. 10689ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool 10690ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 10691ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{ 10692b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 10693ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen switch (arm_or_thumb) 10694ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen { 10695ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen default: 10696ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return false; 10697ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen eModeARM: 10698ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Clear the T bit. 10699558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr &= ~MASK_CPSR_T; 10700ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 10701ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen eModeThumb: 10702ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen // Set the T bit. 10703558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen m_new_inst_cpsr |= MASK_CPSR_T; 10704ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen break; 10705ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen } 10706ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen return true; 10707ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen} 10708ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen 10709ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for 10710ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 10711ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 10712ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool 10713ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport() 10714ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{ 10715ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen return (ArchVersion() >= ARMv7); 10716ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen} 10717ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen 10718bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information 10719bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions. This status 10720bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions. 10721bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult 10722bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 10723bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{ 10724bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint32_t result; 10725bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t carry_out; 10726bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint8_t overflow; 10727bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 10728bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen uint64_t unsigned_sum = x + y + carry_in; 10729bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 10730bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 10731bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen result = UnsignedBits(unsigned_sum, 31, 0); 10732bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen carry_out = (result == unsigned_sum ? 0 : 1); 10733bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen overflow = ((int32_t)result == signed_sum ? 0 : 1); 10734bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 10735bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen AddWithCarryResult res = { result, carry_out, overflow }; 10736bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen return res; 10737bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen} 10738bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen 10739157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenuint32_t 10740e39f22d1a369866808b8739c3cec15063d806833Johnny ChenEmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 10741157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{ 10742e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t reg_kind, reg_num; 10743e39f22d1a369866808b8739c3cec15063d806833Johnny Chen switch (num) 10744157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen { 10745e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case SP_REG: 10746e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 10747e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 10748e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 10749e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case LR_REG: 10750e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 10751e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 10752e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 10753e39f22d1a369866808b8739c3cec15063d806833Johnny Chen case PC_REG: 10754e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindGeneric; 10755e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = LLDB_REGNUM_GENERIC_PC; 10756e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 10757e39f22d1a369866808b8739c3cec15063d806833Johnny Chen default: 107584fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton if (num < SP_REG) 10759e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 10760e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_kind = eRegisterKindDWARF; 10761e39f22d1a369866808b8739c3cec15063d806833Johnny Chen reg_num = dwarf_r0 + num; 10762e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 10763157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen else 10764e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 10765e39f22d1a369866808b8739c3cec15063d806833Johnny Chen assert(0 && "Invalid register number"); 10766e39f22d1a369866808b8739c3cec15063d806833Johnny Chen *success = false; 107674fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton return UINT32_MAX; 10768e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 10769e39f22d1a369866808b8739c3cec15063d806833Johnny Chen break; 10770e39f22d1a369866808b8739c3cec15063d806833Johnny Chen } 10771e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 10772e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // Read our register. 10773e39f22d1a369866808b8739c3cec15063d806833Johnny Chen uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 10774e39f22d1a369866808b8739c3cec15063d806833Johnny Chen 10775e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing an ARM instruction , PC reads as the address of the current 10776e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 8. 10777e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // When executing a Thumb instruction , PC reads as the address of the current 10778e39f22d1a369866808b8739c3cec15063d806833Johnny Chen // instruction plus 4. 10779e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (num == 15) 10780e39f22d1a369866808b8739c3cec15063d806833Johnny Chen { 10781e39f22d1a369866808b8739c3cec15063d806833Johnny Chen if (CurrentInstrSet() == eModeARM) 10782157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen val += 8; 10783e39f22d1a369866808b8739c3cec15063d806833Johnny Chen else 10784e39f22d1a369866808b8739c3cec15063d806833Johnny Chen val += 4; 10785157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen } 10786157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 10787157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen return val; 10788157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen} 10789157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen 10790ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the 10791ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result. 10792ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 10793ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 10794ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual: 10795ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 10796ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then // Can only occur for encoding A1 10797ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ALUWritePC(result); // setflags is always FALSE here 10798ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else 10799ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// R[d] = result; 10800ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if setflags then 10801ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.N = result<31>; 10802ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.Z = IsZeroBit(result); 10803ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// APSR.C = carry; 10804ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// // APSR.V unchanged 10805ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// 10806ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which 10807ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u. 10808ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool 1080910530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 1081010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 1081110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t Rd, 1081210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen bool setflags, 1081310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 1081410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 10815ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{ 10816ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (Rd == 15) 10817ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 10818ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (!ALUWritePC (context, result)) 10819ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 10820ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 10821ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen else 10822ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen { 10823a695f958db37c102d480a9c0780abec262ba8332Johnny Chen uint32_t reg_kind, reg_num; 10824a695f958db37c102d480a9c0780abec262ba8332Johnny Chen switch (Rd) 10825a695f958db37c102d480a9c0780abec262ba8332Johnny Chen { 10826a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case SP_REG: 10827a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindGeneric; 10828a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = LLDB_REGNUM_GENERIC_SP; 10829a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 10830a695f958db37c102d480a9c0780abec262ba8332Johnny Chen case LR_REG: 10831a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindGeneric; 10832a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = LLDB_REGNUM_GENERIC_RA; 10833a695f958db37c102d480a9c0780abec262ba8332Johnny Chen break; 10834a695f958db37c102d480a9c0780abec262ba8332Johnny Chen default: 10835a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_kind = eRegisterKindDWARF; 10836a695f958db37c102d480a9c0780abec262ba8332Johnny Chen reg_num = dwarf_r0 + Rd; 10837a695f958db37c102d480a9c0780abec262ba8332Johnny Chen } 10838a695f958db37c102d480a9c0780abec262ba8332Johnny Chen if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 10839ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return false; 10840ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen if (setflags) 1084110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return WriteFlags (context, result, carry, overflow); 1084210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen } 1084310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return true; 1084410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen} 1084510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen 1084610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the 1084710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual: 1084810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 1084910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>; 1085010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result); 1085110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry; 1085210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow 1085310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// 1085410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means 1085510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags. 1085610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool 1085710530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context, 1085810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t result, 1085910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t carry, 1086010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen const uint32_t overflow) 1086110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{ 10862b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton m_new_inst_cpsr = m_opcode_cpsr; 1086324348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 1086424348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1086510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (carry != ~0u) 1086624348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 1086710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (overflow != ~0u) 1086824348847b93337ad548032e046c71f37e647da26Johnny Chen SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 10869b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_new_inst_cpsr != m_opcode_cpsr) 1087010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen { 1087110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1087210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen return false; 10873ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen } 10874ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen return true; 10875ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen} 10876ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen 1087764c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool 1087864c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::EvaluateInstruction () 1087964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{ 10880c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen // Advance the ITSTATE bits to their values for the next instruction. 10881b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 10882c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen m_it_session.ITAdvance(); 10883c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen 1088464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton return false; 1088564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton} 10886