EmulateInstructionARM.cpp revision 9f687729f0a2fff5dde65ce789c3a02e84c2ffcc
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include <stdlib.h> 11 12#include "EmulateInstructionARM.h" 13#include "lldb/Core/ArchSpec.h" 14#include "lldb/Core/ConstString.h" 15 16#include "Plugins/Process/Utility/ARMDefines.h" 17#include "Plugins/Process/Utility/ARMUtils.h" 18#include "Utility/ARM_DWARF_Registers.h" 19 20#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 21 // and CountTrailingZeros_32 function 22 23using namespace lldb; 24using namespace lldb_private; 25 26//---------------------------------------------------------------------- 27// 28// ITSession implementation 29// 30//---------------------------------------------------------------------- 31 32// A8.6.50 33// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 34static unsigned short CountITSize(unsigned ITMask) { 35 // First count the trailing zeros of the IT mask. 36 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 37 if (TZ > 3) 38 { 39 printf("Encoding error: IT Mask '0000'\n"); 40 return 0; 41 } 42 return (4 - TZ); 43} 44 45// Init ITState. Note that at least one bit is always 1 in mask. 46bool ITSession::InitIT(unsigned short bits7_0) 47{ 48 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 49 if (ITCounter == 0) 50 return false; 51 52 // A8.6.50 IT 53 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 54 if (FirstCond == 0xF) 55 { 56 printf("Encoding error: IT FirstCond '1111'\n"); 57 return false; 58 } 59 if (FirstCond == 0xE && ITCounter != 1) 60 { 61 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 62 return false; 63 } 64 65 ITState = bits7_0; 66 return true; 67} 68 69// Update ITState if necessary. 70void ITSession::ITAdvance() 71{ 72 assert(ITCounter); 73 --ITCounter; 74 if (ITCounter == 0) 75 ITState = 0; 76 else 77 { 78 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 79 SetBits32(ITState, 4, 0, NewITState4_0); 80 } 81} 82 83// Return true if we're inside an IT Block. 84bool ITSession::InITBlock() 85{ 86 return ITCounter != 0; 87} 88 89// Return true if we're the last instruction inside an IT Block. 90bool ITSession::LastInITBlock() 91{ 92 return ITCounter == 1; 93} 94 95// Get condition bits for the current thumb instruction. 96uint32_t ITSession::GetCond() 97{ 98 if (InITBlock()) 99 return Bits32(ITState, 7, 4); 100 else 101 return COND_AL; 102} 103 104// ARM constants used during decoding 105#define REG_RD 0 106#define LDM_REGLIST 1 107#define PC_REG 15 108#define PC_REGLIST_BIT 0x8000 109 110#define ARMv4 (1u << 0) 111#define ARMv4T (1u << 1) 112#define ARMv5T (1u << 2) 113#define ARMv5TE (1u << 3) 114#define ARMv5TEJ (1u << 4) 115#define ARMv6 (1u << 5) 116#define ARMv6K (1u << 6) 117#define ARMv6T2 (1u << 7) 118#define ARMv7 (1u << 8) 119#define ARMv8 (1u << 9) 120#define ARMvAll (0xffffffffu) 121 122#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 123#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 124#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 125 126//---------------------------------------------------------------------- 127// 128// EmulateInstructionARM implementation 129// 130//---------------------------------------------------------------------- 131 132void 133EmulateInstructionARM::Initialize () 134{ 135} 136 137void 138EmulateInstructionARM::Terminate () 139{ 140} 141 142// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 143bool 144EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 145{ 146 EmulateInstruction::Context context; 147 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 148 context.SetNoArgs (); 149 150 uint32_t random_data = rand (); 151 const uint32_t addr_byte_size = GetAddressByteSize(); 152 153 if (!MemAWrite (context, address, random_data, addr_byte_size)) 154 return false; 155 156 return true; 157} 158 159// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 160bool 161EmulateInstructionARM::WriteBits32Unknown (int n) 162{ 163 EmulateInstruction::Context context; 164 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 165 context.SetNoArgs (); 166 167 bool success; 168 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 169 170 if (!success) 171 return false; 172 173 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 174 return false; 175 176 return true; 177} 178 179// Push Multiple Registers stores multiple registers to the stack, storing to 180// consecutive memory locations ending just below the address in SP, and updates 181// SP to point to the start of the stored data. 182bool 183EmulateInstructionARM::EmulatePUSH (ARMEncoding encoding) 184{ 185#if 0 186 // ARM pseudo code... 187 if (ConditionPassed()) 188 { 189 EncodingSpecificOperations(); 190 NullCheckIfThumbEE(13); 191 address = SP - 4*BitCount(registers); 192 193 for (i = 0 to 14) 194 { 195 if (registers<i> == ’1’) 196 { 197 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 198 MemA[address,4] = bits(32) UNKNOWN; 199 else 200 MemA[address,4] = R[i]; 201 address = address + 4; 202 } 203 } 204 205 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 206 MemA[address,4] = PCStoreValue(); 207 208 SP = SP - 4*BitCount(registers); 209 } 210#endif 211 212 bool success = false; 213 const uint32_t opcode = OpcodeAsUnsigned (&success); 214 if (!success) 215 return false; 216 217 if (ConditionPassed()) 218 { 219 const uint32_t addr_byte_size = GetAddressByteSize(); 220 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 221 if (!success) 222 return false; 223 uint32_t registers = 0; 224 uint32_t Rt; // the source register 225 switch (encoding) { 226 case eEncodingT1: 227 registers = Bits32(opcode, 7, 0); 228 // The M bit represents LR. 229 if (Bit32(opcode, 8)) 230 registers |= (1u << 14); 231 // if BitCount(registers) < 1 then UNPREDICTABLE; 232 if (BitCount(registers) < 1) 233 return false; 234 break; 235 case eEncodingT2: 236 // Ignore bits 15 & 13. 237 registers = Bits32(opcode, 15, 0) & ~0xa000; 238 // if BitCount(registers) < 2 then UNPREDICTABLE; 239 if (BitCount(registers) < 2) 240 return false; 241 break; 242 case eEncodingT3: 243 Rt = Bits32(opcode, 15, 12); 244 // if BadReg(t) then UNPREDICTABLE; 245 if (BadReg(Rt)) 246 return false; 247 registers = (1u << Rt); 248 break; 249 case eEncodingA1: 250 registers = Bits32(opcode, 15, 0); 251 // Instead of return false, let's handle the following case as well, 252 // which amounts to pushing one reg onto the full descending stacks. 253 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 254 break; 255 case eEncodingA2: 256 Rt = Bits32(opcode, 15, 12); 257 // if t == 13 then UNPREDICTABLE; 258 if (Rt == dwarf_sp) 259 return false; 260 registers = (1u << Rt); 261 break; 262 default: 263 return false; 264 } 265 addr_t sp_offset = addr_byte_size * BitCount (registers); 266 addr_t addr = sp - sp_offset; 267 uint32_t i; 268 269 EmulateInstruction::Context context; 270 context.type = EmulateInstruction::eContextPushRegisterOnStack; 271 Register dwarf_reg; 272 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 273 for (i=0; i<15; ++i) 274 { 275 if (BitIsSet (registers, i)) 276 { 277 dwarf_reg.num = dwarf_r0 + i; 278 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 279 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 280 if (!success) 281 return false; 282 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 283 return false; 284 addr += addr_byte_size; 285 } 286 } 287 288 if (BitIsSet (registers, 15)) 289 { 290 dwarf_reg.num = dwarf_pc; 291 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 292 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 293 if (!success) 294 return false; 295 if (!MemAWrite (context, addr, pc + 8, addr_byte_size)) 296 return false; 297 } 298 299 context.type = EmulateInstruction::eContextAdjustStackPointer; 300 context.SetImmediateSigned (-sp_offset); 301 302 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 303 return false; 304 } 305 return true; 306} 307 308// Pop Multiple Registers loads multiple registers from the stack, loading from 309// consecutive memory locations staring at the address in SP, and updates 310// SP to point just above the loaded data. 311bool 312EmulateInstructionARM::EmulatePOP (ARMEncoding encoding) 313{ 314#if 0 315 // ARM pseudo code... 316 if (ConditionPassed()) 317 { 318 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 319 address = SP; 320 for i = 0 to 14 321 if registers<i> == ‘1’ then 322 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 323 if registers<15> == ‘1’ then 324 if UnalignedAllowed then 325 LoadWritePC(MemU[address,4]); 326 else 327 LoadWritePC(MemA[address,4]); 328 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 329 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 330 } 331#endif 332 333 bool success = false; 334 const uint32_t opcode = OpcodeAsUnsigned (&success); 335 if (!success) 336 return false; 337 338 if (ConditionPassed()) 339 { 340 const uint32_t addr_byte_size = GetAddressByteSize(); 341 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 342 if (!success) 343 return false; 344 uint32_t registers = 0; 345 uint32_t Rt; // the destination register 346 switch (encoding) { 347 case eEncodingT1: 348 registers = Bits32(opcode, 7, 0); 349 // The P bit represents PC. 350 if (Bit32(opcode, 8)) 351 registers |= (1u << 15); 352 // if BitCount(registers) < 1 then UNPREDICTABLE; 353 if (BitCount(registers) < 1) 354 return false; 355 break; 356 case eEncodingT2: 357 // Ignore bit 13. 358 registers = Bits32(opcode, 15, 0) & ~0x2000; 359 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 360 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 361 return false; 362 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 363 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 364 return false; 365 break; 366 case eEncodingT3: 367 Rt = Bits32(opcode, 15, 12); 368 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 369 if (Rt == 13) 370 return false; 371 if (Rt == 15 && InITBlock() && !LastInITBlock()) 372 return false; 373 registers = (1u << Rt); 374 break; 375 case eEncodingA1: 376 registers = Bits32(opcode, 15, 0); 377 // Instead of return false, let's handle the following case as well, 378 // which amounts to popping one reg from the full descending stacks. 379 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 380 381 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 382 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 383 return false; 384 break; 385 case eEncodingA2: 386 Rt = Bits32(opcode, 15, 12); 387 // if t == 13 then UNPREDICTABLE; 388 if (Rt == dwarf_sp) 389 return false; 390 registers = (1u << Rt); 391 break; 392 default: 393 return false; 394 } 395 addr_t sp_offset = addr_byte_size * BitCount (registers); 396 addr_t addr = sp; 397 uint32_t i, data; 398 399 EmulateInstruction::Context context; 400 context.type = EmulateInstruction::eContextPopRegisterOffStack; 401 Register dwarf_reg; 402 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 403 for (i=0; i<15; ++i) 404 { 405 if (BitIsSet (registers, i)) 406 { 407 dwarf_reg.num = dwarf_r0 + i; 408 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 409 data = MemARead(context, addr, 4, 0, &success); 410 if (!success) 411 return false; 412 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 413 return false; 414 addr += addr_byte_size; 415 } 416 } 417 418 if (BitIsSet (registers, 15)) 419 { 420 dwarf_reg.num = dwarf_pc; 421 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 422 data = MemARead(context, addr, 4, 0, &success); 423 if (!success) 424 return false; 425 // In ARMv5T and above, this is an interworking branch. 426 if (!LoadWritePC(context, data)) 427 return false; 428 addr += addr_byte_size; 429 } 430 431 context.type = EmulateInstruction::eContextAdjustStackPointer; 432 context.SetImmediateSigned (sp_offset); 433 434 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 435 return false; 436 } 437 return true; 438} 439 440// Set r7 or ip to point to saved value residing within the stack. 441// ADD (SP plus immediate) 442bool 443EmulateInstructionARM::EmulateADDRdSPImm (ARMEncoding encoding) 444{ 445#if 0 446 // ARM pseudo code... 447 if (ConditionPassed()) 448 { 449 EncodingSpecificOperations(); 450 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 451 if d == 15 then 452 ALUWritePC(result); // setflags is always FALSE here 453 else 454 R[d] = result; 455 if setflags then 456 APSR.N = result<31>; 457 APSR.Z = IsZeroBit(result); 458 APSR.C = carry; 459 APSR.V = overflow; 460 } 461#endif 462 463 bool success = false; 464 const uint32_t opcode = OpcodeAsUnsigned (&success); 465 if (!success) 466 return false; 467 468 if (ConditionPassed()) 469 { 470 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 471 if (!success) 472 return false; 473 uint32_t Rd; // the destination register 474 uint32_t imm32; 475 switch (encoding) { 476 case eEncodingT1: 477 Rd = 7; 478 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 479 break; 480 case eEncodingA1: 481 Rd = Bits32(opcode, 15, 12); 482 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 483 break; 484 default: 485 return false; 486 } 487 addr_t sp_offset = imm32; 488 addr_t addr = sp + sp_offset; // a pointer to the stack area 489 490 EmulateInstruction::Context context; 491 context.type = EmulateInstruction::eContextRegisterPlusOffset; 492 Register sp_reg; 493 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 494 context.SetRegisterPlusOffset (sp_reg, sp_offset); 495 496 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 497 return false; 498 } 499 return true; 500} 501 502// Set r7 or ip to the current stack pointer. 503// MOV (register) 504bool 505EmulateInstructionARM::EmulateMOVRdSP (ARMEncoding encoding) 506{ 507#if 0 508 // ARM pseudo code... 509 if (ConditionPassed()) 510 { 511 EncodingSpecificOperations(); 512 result = R[m]; 513 if d == 15 then 514 ALUWritePC(result); // setflags is always FALSE here 515 else 516 R[d] = result; 517 if setflags then 518 APSR.N = result<31>; 519 APSR.Z = IsZeroBit(result); 520 // APSR.C unchanged 521 // APSR.V unchanged 522 } 523#endif 524 525 bool success = false; 526 //const uint32_t opcode = OpcodeAsUnsigned (&success); 527 //if (!success) 528 // return false; 529 530 if (ConditionPassed()) 531 { 532 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 533 if (!success) 534 return false; 535 uint32_t Rd; // the destination register 536 switch (encoding) { 537 case eEncodingT1: 538 Rd = 7; 539 break; 540 case eEncodingA1: 541 Rd = 12; 542 break; 543 default: 544 return false; 545 } 546 547 EmulateInstruction::Context context; 548 context.type = EmulateInstruction::eContextRegisterPlusOffset; 549 Register sp_reg; 550 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 551 context.SetRegisterPlusOffset (sp_reg, 0); 552 553 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 554 return false; 555 } 556 return true; 557} 558 559// Move from high register (r8-r15) to low register (r0-r7). 560// MOV (register) 561bool 562EmulateInstructionARM::EmulateMOVLowHigh (ARMEncoding encoding) 563{ 564 return EmulateMOVRdRm (encoding); 565} 566 567// Move from register to register. 568// MOV (register) 569bool 570EmulateInstructionARM::EmulateMOVRdRm (ARMEncoding encoding) 571{ 572#if 0 573 // ARM pseudo code... 574 if (ConditionPassed()) 575 { 576 EncodingSpecificOperations(); 577 result = R[m]; 578 if d == 15 then 579 ALUWritePC(result); // setflags is always FALSE here 580 else 581 R[d] = result; 582 if setflags then 583 APSR.N = result<31>; 584 APSR.Z = IsZeroBit(result); 585 // APSR.C unchanged 586 // APSR.V unchanged 587 } 588#endif 589 590 bool success = false; 591 const uint32_t opcode = OpcodeAsUnsigned (&success); 592 if (!success) 593 return false; 594 595 if (ConditionPassed()) 596 { 597 uint32_t Rm; // the source register 598 uint32_t Rd; // the destination register 599 bool setflags; 600 switch (encoding) { 601 case eEncodingT1: 602 Rm = Bits32(opcode, 6, 3); 603 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1); 604 setflags = false; 605 break; 606 case eEncodingT2: 607 Rm = Bits32(opcode, 5, 3); 608 Rd = Bits32(opcode, 2, 1); 609 setflags = true; 610 break; 611 default: 612 return false; 613 } 614 uint32_t result = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 615 if (!success) 616 return false; 617 618 // The context specifies that Rm is to be moved into Rd. 619 EmulateInstruction::Context context; 620 context.type = EmulateInstruction::eContextRegisterPlusOffset; 621 Register dwarf_reg; 622 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 623 context.SetRegisterPlusOffset (dwarf_reg, 0); 624 625 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 626 return false; 627 } 628 return true; 629} 630 631// Move (immediate) writes an immediate value to the destination register. It 632// can optionally update the condition flags based on the value. 633// MOV (immediate) 634bool 635EmulateInstructionARM::EmulateMOVRdImm (ARMEncoding encoding) 636{ 637#if 0 638 // ARM pseudo code... 639 if (ConditionPassed()) 640 { 641 EncodingSpecificOperations(); 642 result = imm32; 643 if d == 15 then // Can only occur for ARM encoding 644 ALUWritePC(result); // setflags is always FALSE here 645 else 646 R[d] = result; 647 if setflags then 648 APSR.N = result<31>; 649 APSR.Z = IsZeroBit(result); 650 APSR.C = carry; 651 // APSR.V unchanged 652 } 653#endif 654 bool success = false; 655 const uint32_t opcode = OpcodeAsUnsigned (&success); 656 if (!success) 657 return false; 658 659 if (ConditionPassed()) 660 { 661 uint32_t Rd; // the destination register 662 uint32_t imm12; // some intermediate result 663 uint32_t imm32; // the immediate value to be written to Rd 664 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 665 bool setflags; 666 switch (encoding) { 667 case eEncodingT1: 668 Rd = Bits32(opcode, 11, 8); 669 setflags = !InITBlock(); 670 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 671 carry = Bit32(m_inst_cpsr, CPSR_C); 672 break; 673 case eEncodingT2: 674 Rd = Bits32(opcode, 15, 12); 675 setflags = BitIsSet(opcode, 20); 676 imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0); 677 imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 678 if (BadReg(Rd)) 679 return false; 680 break; 681 default: 682 return false; 683 } 684 uint32_t result = imm32; 685 686 // The context specifies that an immediate is to be moved into Rd. 687 EmulateInstruction::Context context; 688 context.type = EmulateInstruction::eContextImmediate; 689 context.SetNoArgs (); 690 691 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 692 return false; 693 } 694 return true; 695} 696 697// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 698// the destination register. It can optionally update the condition flags based 699// on the value. 700// MVN (immediate) 701bool 702EmulateInstructionARM::EmulateMVNRdImm (ARMEncoding encoding) 703{ 704#if 0 705 // ARM pseudo code... 706 if (ConditionPassed()) 707 { 708 EncodingSpecificOperations(); 709 result = NOT(imm32); 710 if d == 15 then // Can only occur for ARM encoding 711 ALUWritePC(result); // setflags is always FALSE here 712 else 713 R[d] = result; 714 if setflags then 715 APSR.N = result<31>; 716 APSR.Z = IsZeroBit(result); 717 APSR.C = carry; 718 // APSR.V unchanged 719 } 720#endif 721 bool success = false; 722 const uint32_t opcode = OpcodeAsUnsigned (&success); 723 if (!success) 724 return false; 725 726 if (ConditionPassed()) 727 { 728 uint32_t Rd; // the destination register 729 uint32_t imm12; // the first operand to ThumbExpandImm_C or ARMExpandImm_C 730 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 731 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 732 bool setflags; 733 switch (encoding) { 734 case eEncodingT1: 735 Rd = Bits32(opcode, 11, 8); 736 setflags = BitIsSet(opcode, 20); 737 imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0); 738 imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 739 break; 740 case eEncodingA1: 741 Rd = Bits32(opcode, 15, 12); 742 setflags = BitIsSet(opcode, 20); 743 imm12 = Bits32(opcode, 11, 0); 744 imm32 = ARMExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 745 break; 746 default: 747 return false; 748 } 749 uint32_t result = ~imm32; 750 751 // The context specifies that an immediate is to be moved into Rd. 752 EmulateInstruction::Context context; 753 context.type = EmulateInstruction::eContextImmediate; 754 context.SetNoArgs (); 755 756 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 757 return false; 758 } 759 return true; 760} 761 762// PC relative immediate load into register, possibly followed by ADD (SP plus register). 763// LDR (literal) 764bool 765EmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding) 766{ 767#if 0 768 // ARM pseudo code... 769 if (ConditionPassed()) 770 { 771 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 772 base = Align(PC,4); 773 address = if add then (base + imm32) else (base - imm32); 774 data = MemU[address,4]; 775 if t == 15 then 776 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 777 elsif UnalignedSupport() || address<1:0> = ‘00’ then 778 R[t] = data; 779 else // Can only apply before ARMv7 780 if CurrentInstrSet() == InstrSet_ARM then 781 R[t] = ROR(data, 8*UInt(address<1:0>)); 782 else 783 R[t] = bits(32) UNKNOWN; 784 } 785#endif 786 787 bool success = false; 788 const uint32_t opcode = OpcodeAsUnsigned (&success); 789 if (!success) 790 return false; 791 792 if (ConditionPassed()) 793 { 794 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 795 if (!success) 796 return false; 797 798 // PC relative immediate load context 799 EmulateInstruction::Context context; 800 context.type = EmulateInstruction::eContextRegisterPlusOffset; 801 Register pc_reg; 802 pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 803 context.SetRegisterPlusOffset (pc_reg, 0); 804 805 uint32_t Rt; // the destination register 806 uint32_t imm32; // immediate offset from the PC 807 bool add; // +imm32 or -imm32? 808 addr_t base; // the base address 809 addr_t address; // the PC relative address 810 uint32_t data; // the literal data value from the PC relative load 811 switch (encoding) { 812 case eEncodingT1: 813 Rt = Bits32(opcode, 10, 8); 814 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 815 add = true; 816 base = Align(pc + 4, 4); 817 context.SetRegisterPlusOffset (pc_reg, 4 + imm32); 818 break; 819 case eEncodingT2: 820 Rt = Bits32(opcode, 15, 12); 821 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 822 add = BitIsSet(opcode, 23); 823 if (Rt == 15 && InITBlock() && !LastInITBlock()) 824 return false; 825 base = Align(pc + 4, 4); 826 context.SetRegisterPlusOffset (pc_reg, 4 + imm32); 827 break; 828 default: 829 return false; 830 } 831 832 if (add) 833 address = base + imm32; 834 else 835 address = base - imm32; 836 data = MemURead(context, address, 4, 0, &success); 837 if (!success) 838 return false; 839 840 if (Rt == 15) 841 { 842 if (Bits32(address, 1, 0) == 0) 843 { 844 // In ARMv5T and above, this is an interworking branch. 845 if (!LoadWritePC(context, data)) 846 return false; 847 } 848 else 849 return false; 850 } 851 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 852 { 853 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 854 return false; 855 } 856 else // We don't handle ARM for now. 857 return false; 858 859 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 860 return false; 861 } 862 return true; 863} 864 865// An add operation to adjust the SP. 866// ADD (SP plus immediate) 867bool 868EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding) 869{ 870#if 0 871 // ARM pseudo code... 872 if (ConditionPassed()) 873 { 874 EncodingSpecificOperations(); 875 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 876 if d == 15 then // Can only occur for ARM encoding 877 ALUWritePC(result); // setflags is always FALSE here 878 else 879 R[d] = result; 880 if setflags then 881 APSR.N = result<31>; 882 APSR.Z = IsZeroBit(result); 883 APSR.C = carry; 884 APSR.V = overflow; 885 } 886#endif 887 888 bool success = false; 889 const uint32_t opcode = OpcodeAsUnsigned (&success); 890 if (!success) 891 return false; 892 893 if (ConditionPassed()) 894 { 895 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 896 if (!success) 897 return false; 898 uint32_t imm32; // the immediate operand 899 switch (encoding) { 900 case eEncodingT2: 901 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 902 break; 903 default: 904 return false; 905 } 906 addr_t sp_offset = imm32; 907 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 908 909 EmulateInstruction::Context context; 910 context.type = EmulateInstruction::eContextAdjustStackPointer; 911 context.SetImmediateSigned (sp_offset); 912 913 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 914 return false; 915 } 916 return true; 917} 918 919// An add operation to adjust the SP. 920// ADD (SP plus register) 921bool 922EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding) 923{ 924#if 0 925 // ARM pseudo code... 926 if (ConditionPassed()) 927 { 928 EncodingSpecificOperations(); 929 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 930 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 931 if d == 15 then 932 ALUWritePC(result); // setflags is always FALSE here 933 else 934 R[d] = result; 935 if setflags then 936 APSR.N = result<31>; 937 APSR.Z = IsZeroBit(result); 938 APSR.C = carry; 939 APSR.V = overflow; 940 } 941#endif 942 943 bool success = false; 944 const uint32_t opcode = OpcodeAsUnsigned (&success); 945 if (!success) 946 return false; 947 948 if (ConditionPassed()) 949 { 950 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 951 if (!success) 952 return false; 953 uint32_t Rm; // the second operand 954 switch (encoding) { 955 case eEncodingT2: 956 Rm = Bits32(opcode, 6, 3); 957 break; 958 default: 959 return false; 960 } 961 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 962 if (!success) 963 return false; 964 965 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 966 967 EmulateInstruction::Context context; 968 context.type = EmulateInstruction::eContextAdjustStackPointer; 969 context.SetImmediateSigned (reg_value); 970 971 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 972 return false; 973 } 974 return true; 975} 976 977// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 978// at a PC-relative address, and changes instruction set from ARM to Thumb, or 979// from Thumb to ARM. 980// BLX (immediate) 981bool 982EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 983{ 984#if 0 985 // ARM pseudo code... 986 if (ConditionPassed()) 987 { 988 EncodingSpecificOperations(); 989 if CurrentInstrSet() == InstrSet_ARM then 990 LR = PC - 4; 991 else 992 LR = PC<31:1> : '1'; 993 if targetInstrSet == InstrSet_ARM then 994 targetAddress = Align(PC,4) + imm32; 995 else 996 targetAddress = PC + imm32; 997 SelectInstrSet(targetInstrSet); 998 BranchWritePC(targetAddress); 999 } 1000#endif 1001 1002 bool success = false; 1003 const uint32_t opcode = OpcodeAsUnsigned (&success); 1004 if (!success) 1005 return false; 1006 1007 if (ConditionPassed()) 1008 { 1009 EmulateInstruction::Context context; 1010 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1011 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1012 if (!success) 1013 return false; 1014 addr_t lr; // next instruction address 1015 addr_t target; // target address 1016 int32_t imm32; // PC-relative offset 1017 switch (encoding) { 1018 case eEncodingT1: 1019 { 1020 lr = (pc + 4) | 1u; // return address 1021 uint32_t S = Bit32(opcode, 26); 1022 uint32_t imm10 = Bits32(opcode, 25, 16); 1023 uint32_t J1 = Bit32(opcode, 13); 1024 uint32_t J2 = Bit32(opcode, 11); 1025 uint32_t imm11 = Bits32(opcode, 10, 0); 1026 uint32_t I1 = !(J1 ^ S); 1027 uint32_t I2 = !(J2 ^ S); 1028 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1029 imm32 = llvm::SignExtend32<25>(imm25); 1030 target = pc + 4 + imm32; 1031 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1032 if (InITBlock() && !LastInITBlock()) 1033 return false; 1034 break; 1035 } 1036 case eEncodingT2: 1037 { 1038 lr = (pc + 4) | 1u; // return address 1039 uint32_t S = Bit32(opcode, 26); 1040 uint32_t imm10H = Bits32(opcode, 25, 16); 1041 uint32_t J1 = Bit32(opcode, 13); 1042 uint32_t J2 = Bit32(opcode, 11); 1043 uint32_t imm10L = Bits32(opcode, 10, 1); 1044 uint32_t I1 = !(J1 ^ S); 1045 uint32_t I2 = !(J2 ^ S); 1046 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1047 imm32 = llvm::SignExtend32<25>(imm25); 1048 target = Align(pc + 4, 4) + imm32; 1049 context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1050 if (InITBlock() && !LastInITBlock()) 1051 return false; 1052 break; 1053 } 1054 case eEncodingA1: 1055 lr = pc + 4; // return address 1056 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1057 target = Align(pc + 8, 4) + imm32; 1058 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1059 break; 1060 case eEncodingA2: 1061 lr = pc + 4; // return address 1062 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1063 target = pc + 8 + imm32; 1064 context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 1065 break; 1066 default: 1067 return false; 1068 } 1069 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1070 return false; 1071 if (!BranchWritePC(context, target)) 1072 return false; 1073 } 1074 return true; 1075} 1076 1077// Branch with Link and Exchange (register) calls a subroutine at an address and 1078// instruction set specified by a register. 1079// BLX (register) 1080bool 1081EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 1082{ 1083#if 0 1084 // ARM pseudo code... 1085 if (ConditionPassed()) 1086 { 1087 EncodingSpecificOperations(); 1088 target = R[m]; 1089 if CurrentInstrSet() == InstrSet_ARM then 1090 next_instr_addr = PC - 4; 1091 LR = next_instr_addr; 1092 else 1093 next_instr_addr = PC - 2; 1094 LR = next_instr_addr<31:1> : ‘1’; 1095 BXWritePC(target); 1096 } 1097#endif 1098 1099 bool success = false; 1100 const uint32_t opcode = OpcodeAsUnsigned (&success); 1101 if (!success) 1102 return false; 1103 1104 if (ConditionPassed()) 1105 { 1106 EmulateInstruction::Context context; 1107 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1108 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1109 addr_t lr; // next instruction address 1110 if (!success) 1111 return false; 1112 uint32_t Rm; // the register with the target address 1113 switch (encoding) { 1114 case eEncodingT1: 1115 lr = (pc + 2) | 1u; // return address 1116 Rm = Bits32(opcode, 6, 3); 1117 // if m == 15 then UNPREDICTABLE; 1118 if (Rm == 15) 1119 return false; 1120 if (InITBlock() && !LastInITBlock()) 1121 return false; 1122 break; 1123 case eEncodingA1: 1124 lr = pc + 4; // return address 1125 Rm = Bits32(opcode, 3, 0); 1126 // if m == 15 then UNPREDICTABLE; 1127 if (Rm == 15) 1128 return false; 1129 break; 1130 default: 1131 return false; 1132 } 1133 addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1134 if (!success) 1135 return false; 1136 Register dwarf_reg; 1137 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1138 context.SetRegister (dwarf_reg); 1139 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1140 return false; 1141 if (!BXWritePC(context, target)) 1142 return false; 1143 } 1144 return true; 1145} 1146 1147// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1148// BX 1149bool 1150EmulateInstructionARM::EmulateBXRm (ARMEncoding encoding) 1151{ 1152#if 0 1153 // ARM pseudo code... 1154 if (ConditionPassed()) 1155 { 1156 EncodingSpecificOperations(); 1157 BXWritePC(R[m]); 1158 } 1159#endif 1160 1161 bool success = false; 1162 const uint32_t opcode = OpcodeAsUnsigned (&success); 1163 if (!success) 1164 return false; 1165 1166 if (ConditionPassed()) 1167 { 1168 EmulateInstruction::Context context; 1169 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1170 uint32_t Rm; // the register with the target address 1171 switch (encoding) { 1172 case eEncodingT1: 1173 Rm = Bits32(opcode, 6, 3); 1174 if (InITBlock() && !LastInITBlock()) 1175 return false; 1176 break; 1177 case eEncodingA1: 1178 Rm = Bits32(opcode, 3, 0); 1179 break; 1180 default: 1181 return false; 1182 } 1183 addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1184 if (!success) 1185 return false; 1186 1187 Register dwarf_reg; 1188 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1189 context.SetRegister (dwarf_reg); 1190 if (!BXWritePC(context, target)) 1191 return false; 1192 } 1193 return true; 1194} 1195 1196// Set r7 to point to some ip offset. 1197// SUB (immediate) 1198bool 1199EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding) 1200{ 1201#if 0 1202 // ARM pseudo code... 1203 if (ConditionPassed()) 1204 { 1205 EncodingSpecificOperations(); 1206 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1207 if d == 15 then // Can only occur for ARM encoding 1208 ALUWritePC(result); // setflags is always FALSE here 1209 else 1210 R[d] = result; 1211 if setflags then 1212 APSR.N = result<31>; 1213 APSR.Z = IsZeroBit(result); 1214 APSR.C = carry; 1215 APSR.V = overflow; 1216 } 1217#endif 1218 1219 bool success = false; 1220 const uint32_t opcode = OpcodeAsUnsigned (&success); 1221 if (!success) 1222 return false; 1223 1224 if (ConditionPassed()) 1225 { 1226 const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success); 1227 if (!success) 1228 return false; 1229 uint32_t imm32; 1230 switch (encoding) { 1231 case eEncodingA1: 1232 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1233 break; 1234 default: 1235 return false; 1236 } 1237 addr_t ip_offset = imm32; 1238 addr_t addr = ip - ip_offset; // the adjusted ip value 1239 1240 EmulateInstruction::Context context; 1241 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1242 Register dwarf_reg; 1243 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 1244 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1245 1246 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1247 return false; 1248 } 1249 return true; 1250} 1251 1252// Set ip to point to some stack offset. 1253// SUB (SP minus immediate) 1254bool 1255EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding) 1256{ 1257#if 0 1258 // ARM pseudo code... 1259 if (ConditionPassed()) 1260 { 1261 EncodingSpecificOperations(); 1262 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1263 if d == 15 then // Can only occur for ARM encoding 1264 ALUWritePC(result); // setflags is always FALSE here 1265 else 1266 R[d] = result; 1267 if setflags then 1268 APSR.N = result<31>; 1269 APSR.Z = IsZeroBit(result); 1270 APSR.C = carry; 1271 APSR.V = overflow; 1272 } 1273#endif 1274 1275 bool success = false; 1276 const uint32_t opcode = OpcodeAsUnsigned (&success); 1277 if (!success) 1278 return false; 1279 1280 if (ConditionPassed()) 1281 { 1282 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1283 if (!success) 1284 return false; 1285 uint32_t imm32; 1286 switch (encoding) { 1287 case eEncodingA1: 1288 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1289 break; 1290 default: 1291 return false; 1292 } 1293 addr_t sp_offset = imm32; 1294 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1295 1296 EmulateInstruction::Context context; 1297 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1298 Register dwarf_reg; 1299 dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 1300 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1301 1302 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1303 return false; 1304 } 1305 return true; 1306} 1307 1308// A sub operation to adjust the SP -- allocate space for local storage. 1309bool 1310EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding) 1311{ 1312#if 0 1313 // ARM pseudo code... 1314 if (ConditionPassed()) 1315 { 1316 EncodingSpecificOperations(); 1317 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1318 if d == 15 then // Can only occur for ARM encoding 1319 ALUWritePC(result); // setflags is always FALSE here 1320 else 1321 R[d] = result; 1322 if setflags then 1323 APSR.N = result<31>; 1324 APSR.Z = IsZeroBit(result); 1325 APSR.C = carry; 1326 APSR.V = overflow; 1327 } 1328#endif 1329 1330 bool success = false; 1331 const uint32_t opcode = OpcodeAsUnsigned (&success); 1332 if (!success) 1333 return false; 1334 1335 if (ConditionPassed()) 1336 { 1337 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1338 if (!success) 1339 return false; 1340 uint32_t imm32; 1341 switch (encoding) { 1342 case eEncodingT1: 1343 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1344 case eEncodingT2: 1345 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1346 break; 1347 case eEncodingT3: 1348 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1349 break; 1350 case eEncodingA1: 1351 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1352 break; 1353 default: 1354 return false; 1355 } 1356 addr_t sp_offset = imm32; 1357 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1358 1359 EmulateInstruction::Context context; 1360 context.type = EmulateInstruction::eContextAdjustStackPointer; 1361 context.SetImmediateSigned (-sp_offset); 1362 1363 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1364 return false; 1365 } 1366 return true; 1367} 1368 1369// A store operation to the stack that also updates the SP. 1370bool 1371EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1372{ 1373#if 0 1374 // ARM pseudo code... 1375 if (ConditionPassed()) 1376 { 1377 EncodingSpecificOperations(); 1378 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1379 address = if index then offset_addr else R[n]; 1380 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1381 if wback then R[n] = offset_addr; 1382 } 1383#endif 1384 1385 bool success = false; 1386 const uint32_t opcode = OpcodeAsUnsigned (&success); 1387 if (!success) 1388 return false; 1389 1390 if (ConditionPassed()) 1391 { 1392 const uint32_t addr_byte_size = GetAddressByteSize(); 1393 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1394 if (!success) 1395 return false; 1396 uint32_t Rt; // the source register 1397 uint32_t imm12; 1398 switch (encoding) { 1399 case eEncodingA1: 1400 Rt = Bits32(opcode, 15, 12); 1401 imm12 = Bits32(opcode, 11, 0); 1402 break; 1403 default: 1404 return false; 1405 } 1406 addr_t sp_offset = imm12; 1407 addr_t addr = sp - sp_offset; 1408 1409 EmulateInstruction::Context context; 1410 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1411 Register dwarf_reg; 1412 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1413 if (Rt != 15) 1414 { 1415 dwarf_reg.num = dwarf_r0 + Rt; 1416 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1417 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1418 if (!success) 1419 return false; 1420 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1421 return false; 1422 } 1423 else 1424 { 1425 dwarf_reg.num = dwarf_pc; 1426 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1427 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1428 if (!success) 1429 return false; 1430 if (!MemUWrite (context, addr, pc + 8, addr_byte_size)) 1431 return false; 1432 } 1433 1434 context.type = EmulateInstruction::eContextAdjustStackPointer; 1435 context.SetImmediateSigned (-sp_offset); 1436 1437 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1438 return false; 1439 } 1440 return true; 1441} 1442 1443// Vector Push stores multiple extension registers to the stack. 1444// It also updates SP to point to the start of the stored data. 1445bool 1446EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1447{ 1448#if 0 1449 // ARM pseudo code... 1450 if (ConditionPassed()) 1451 { 1452 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1453 address = SP - imm32; 1454 SP = SP - imm32; 1455 if single_regs then 1456 for r = 0 to regs-1 1457 MemA[address,4] = S[d+r]; address = address+4; 1458 else 1459 for r = 0 to regs-1 1460 // Store as two word-aligned words in the correct order for current endianness. 1461 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1462 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1463 address = address+8; 1464 } 1465#endif 1466 1467 bool success = false; 1468 const uint32_t opcode = OpcodeAsUnsigned (&success); 1469 if (!success) 1470 return false; 1471 1472 if (ConditionPassed()) 1473 { 1474 const uint32_t addr_byte_size = GetAddressByteSize(); 1475 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1476 if (!success) 1477 return false; 1478 bool single_regs; 1479 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1480 uint32_t imm32; // stack offset 1481 uint32_t regs; // number of registers 1482 switch (encoding) { 1483 case eEncodingT1: 1484 case eEncodingA1: 1485 single_regs = false; 1486 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1487 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1488 // If UInt(imm8) is odd, see "FSTMX". 1489 regs = Bits32(opcode, 7, 0) / 2; 1490 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1491 if (regs == 0 || regs > 16 || (d + regs) > 32) 1492 return false; 1493 break; 1494 case eEncodingT2: 1495 case eEncodingA2: 1496 single_regs = true; 1497 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1498 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1499 regs = Bits32(opcode, 7, 0); 1500 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1501 if (regs == 0 || regs > 16 || (d + regs) > 32) 1502 return false; 1503 break; 1504 default: 1505 return false; 1506 } 1507 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1508 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1509 addr_t sp_offset = imm32; 1510 addr_t addr = sp - sp_offset; 1511 uint32_t i; 1512 1513 EmulateInstruction::Context context; 1514 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1515 Register dwarf_reg; 1516 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1517 for (i=d; i<regs; ++i) 1518 { 1519 dwarf_reg.num = start_reg + i; 1520 context.SetRegisterPlusOffset ( dwarf_reg, addr - sp); 1521 // uint64_t to accommodate 64-bit registers. 1522 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1523 if (!success) 1524 return false; 1525 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 1526 return false; 1527 addr += reg_byte_size; 1528 } 1529 1530 context.type = EmulateInstruction::eContextAdjustStackPointer; 1531 context.SetImmediateSigned (-sp_offset); 1532 1533 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1534 return false; 1535 } 1536 return true; 1537} 1538 1539// Vector Pop loads multiple extension registers from the stack. 1540// It also updates SP to point just above the loaded data. 1541bool 1542EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1543{ 1544#if 0 1545 // ARM pseudo code... 1546 if (ConditionPassed()) 1547 { 1548 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1549 address = SP; 1550 SP = SP + imm32; 1551 if single_regs then 1552 for r = 0 to regs-1 1553 S[d+r] = MemA[address,4]; address = address+4; 1554 else 1555 for r = 0 to regs-1 1556 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1557 // Combine the word-aligned words in the correct order for current endianness. 1558 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1559 } 1560#endif 1561 1562 bool success = false; 1563 const uint32_t opcode = OpcodeAsUnsigned (&success); 1564 if (!success) 1565 return false; 1566 1567 if (ConditionPassed()) 1568 { 1569 const uint32_t addr_byte_size = GetAddressByteSize(); 1570 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1571 if (!success) 1572 return false; 1573 bool single_regs; 1574 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1575 uint32_t imm32; // stack offset 1576 uint32_t regs; // number of registers 1577 switch (encoding) { 1578 case eEncodingT1: 1579 case eEncodingA1: 1580 single_regs = false; 1581 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1582 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1583 // If UInt(imm8) is odd, see "FLDMX". 1584 regs = Bits32(opcode, 7, 0) / 2; 1585 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1586 if (regs == 0 || regs > 16 || (d + regs) > 32) 1587 return false; 1588 break; 1589 case eEncodingT2: 1590 case eEncodingA2: 1591 single_regs = true; 1592 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1593 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1594 regs = Bits32(opcode, 7, 0); 1595 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1596 if (regs == 0 || regs > 16 || (d + regs) > 32) 1597 return false; 1598 break; 1599 default: 1600 return false; 1601 } 1602 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1603 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1604 addr_t sp_offset = imm32; 1605 addr_t addr = sp; 1606 uint32_t i; 1607 uint64_t data; // uint64_t to accomodate 64-bit registers. 1608 1609 EmulateInstruction::Context context; 1610 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1611 Register dwarf_reg; 1612 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1613 for (i=d; i<regs; ++i) 1614 { 1615 dwarf_reg.num = start_reg + i; 1616 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1617 data = MemARead(context, addr, reg_byte_size, 0, &success); 1618 if (!success) 1619 return false; 1620 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1621 return false; 1622 addr += reg_byte_size; 1623 } 1624 1625 context.type = EmulateInstruction::eContextAdjustStackPointer; 1626 context.SetImmediateSigned (sp_offset); 1627 1628 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1629 return false; 1630 } 1631 return true; 1632} 1633 1634// SVC (previously SWI) 1635bool 1636EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1637{ 1638#if 0 1639 // ARM pseudo code... 1640 if (ConditionPassed()) 1641 { 1642 EncodingSpecificOperations(); 1643 CallSupervisor(); 1644 } 1645#endif 1646 1647 bool success = false; 1648 const uint32_t opcode = OpcodeAsUnsigned (&success); 1649 if (!success) 1650 return false; 1651 1652 if (ConditionPassed()) 1653 { 1654 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1655 addr_t lr; // next instruction address 1656 if (!success) 1657 return false; 1658 uint32_t imm32; // the immediate constant 1659 uint32_t mode; // ARM or Thumb mode 1660 switch (encoding) { 1661 case eEncodingT1: 1662 lr = (pc + 2) | 1u; // return address 1663 imm32 = Bits32(opcode, 7, 0); 1664 mode = eModeThumb; 1665 break; 1666 case eEncodingA1: 1667 lr = pc + 4; // return address 1668 imm32 = Bits32(opcode, 23, 0); 1669 mode = eModeARM; 1670 break; 1671 default: 1672 return false; 1673 } 1674 1675 EmulateInstruction::Context context; 1676 context.type = EmulateInstruction::eContextSupervisorCall; 1677 context.SetModeAndImmediate (mode, imm32); 1678 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1679 return false; 1680 } 1681 return true; 1682} 1683 1684// If Then makes up to four following instructions (the IT block) conditional. 1685bool 1686EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1687{ 1688#if 0 1689 // ARM pseudo code... 1690 EncodingSpecificOperations(); 1691 ITSTATE.IT<7:0> = firstcond:mask; 1692#endif 1693 1694 bool success = false; 1695 const uint32_t opcode = OpcodeAsUnsigned (&success); 1696 if (!success) 1697 return false; 1698 1699 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1700 return true; 1701} 1702 1703// Branch causes a branch to a target address. 1704bool 1705EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1706{ 1707#if 0 1708 // ARM pseudo code... 1709 if (ConditionPassed()) 1710 { 1711 EncodingSpecificOperations(); 1712 BranchWritePC(PC + imm32); 1713 } 1714#endif 1715 1716 bool success = false; 1717 const uint32_t opcode = OpcodeAsUnsigned (&success); 1718 if (!success) 1719 return false; 1720 1721 if (ConditionPassed()) 1722 { 1723 EmulateInstruction::Context context; 1724 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1725 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1726 if (!success) 1727 return false; 1728 addr_t target; // target address 1729 int32_t imm32; // PC-relative offset 1730 switch (encoding) { 1731 case eEncodingT1: 1732 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1733 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1734 target = pc + 4 + imm32; 1735 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1736 break; 1737 case eEncodingT2: 1738 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1739 target = pc + 4 + imm32; 1740 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1741 break; 1742 case eEncodingT3: 1743 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1744 { 1745 uint32_t S = Bit32(opcode, 26); 1746 uint32_t imm6 = Bits32(opcode, 21, 16); 1747 uint32_t J1 = Bit32(opcode, 13); 1748 uint32_t J2 = Bit32(opcode, 11); 1749 uint32_t imm11 = Bits32(opcode, 10, 0); 1750 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 1751 imm32 = llvm::SignExtend32<21>(imm21); 1752 target = pc + 4 + imm32; 1753 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1754 break; 1755 } 1756 case eEncodingT4: 1757 { 1758 uint32_t S = Bit32(opcode, 26); 1759 uint32_t imm10 = Bits32(opcode, 25, 16); 1760 uint32_t J1 = Bit32(opcode, 13); 1761 uint32_t J2 = Bit32(opcode, 11); 1762 uint32_t imm11 = Bits32(opcode, 10, 0); 1763 uint32_t I1 = !(J1 ^ S); 1764 uint32_t I2 = !(J2 ^ S); 1765 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1766 imm32 = llvm::SignExtend32<25>(imm25); 1767 target = pc + 4 + imm32; 1768 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1769 break; 1770 } 1771 case eEncodingA1: 1772 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1773 target = pc + 8 + imm32; 1774 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1775 break; 1776 default: 1777 return false; 1778 } 1779 if (!BranchWritePC(context, target)) 1780 return false; 1781 } 1782 return true; 1783} 1784 1785// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 1786// zero and conditionally branch forward a constant value. They do not affect the condition flags. 1787// CBNZ, CBZ 1788bool 1789EmulateInstructionARM::EmulateCB (ARMEncoding encoding) 1790{ 1791#if 0 1792 // ARM pseudo code... 1793 EncodingSpecificOperations(); 1794 if nonzero ^ IsZero(R[n]) then 1795 BranchWritePC(PC + imm32); 1796#endif 1797 1798 bool success = false; 1799 const uint32_t opcode = OpcodeAsUnsigned (&success); 1800 if (!success) 1801 return false; 1802 1803 // Read the register value from the operand register Rn. 1804 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success); 1805 if (!success) 1806 return false; 1807 1808 EmulateInstruction::Context context; 1809 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1810 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1811 if (!success) 1812 return false; 1813 1814 addr_t target; // target address 1815 uint32_t imm32; // PC-relative offset to branch forward 1816 bool nonzero; 1817 switch (encoding) { 1818 case eEncodingT1: 1819 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 1820 nonzero = BitIsSet(opcode, 11); 1821 target = pc + 4 + imm32; 1822 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1823 break; 1824 default: 1825 return false; 1826 } 1827 if (nonzero ^ (reg_val == 0)) 1828 if (!BranchWritePC(context, target)) 1829 return false; 1830 1831 return true; 1832} 1833 1834// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 1835// A base register provides a pointer to the table, and a second register supplies an index into the table. 1836// The branch length is twice the value of the byte returned from the table. 1837// 1838// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 1839// A base register provides a pointer to the table, and a second register supplies an index into the table. 1840// The branch length is twice the value of the halfword returned from the table. 1841// TBB, TBH 1842bool 1843EmulateInstructionARM::EmulateTB (ARMEncoding encoding) 1844{ 1845#if 0 1846 // ARM pseudo code... 1847 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 1848 if is_tbh then 1849 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 1850 else 1851 halfwords = UInt(MemU[R[n]+R[m], 1]); 1852 BranchWritePC(PC + 2*halfwords); 1853#endif 1854 1855 bool success = false; 1856 const uint32_t opcode = OpcodeAsUnsigned (&success); 1857 if (!success) 1858 return false; 1859 1860 uint32_t Rn; // the base register which contains the address of the table of branch lengths 1861 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 1862 bool is_tbh; // true if table branch halfword 1863 switch (encoding) { 1864 case eEncodingT1: 1865 Rn = Bits32(opcode, 19, 16); 1866 Rm = Bits32(opcode, 3, 0); 1867 is_tbh = BitIsSet(opcode, 4); 1868 if (Rn == 13 || BadReg(Rm)) 1869 return false; 1870 if (InITBlock() && !LastInITBlock()) 1871 return false; 1872 break; 1873 default: 1874 return false; 1875 } 1876 1877 // Read the address of the table from the operand register Rn. 1878 // The PC can be used, in which case the table immediately follows this instruction. 1879 uint32_t base = 1880 Rn == 15 ? (ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success) + 4) 1881 : ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1882 if (!success) 1883 return false; 1884 1885 // the table index 1886 uint32_t index = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1887 if (!success) 1888 return false; 1889 1890 // the offsetted table address 1891 addr_t addr = base + (is_tbh ? index*2 : index); 1892 1893 // PC-relative offset to branch forward 1894 EmulateInstruction::Context context; 1895 context.type = EmulateInstruction::eContextTableBranchReadMemory; 1896 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 1897 if (!success) 1898 return false; 1899 1900 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1901 if (!success) 1902 return false; 1903 1904 // target address 1905 addr_t target = pc + 4 + offset; 1906 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1907 context.SetModeAndImmediateSigned (eModeThumb, 4 + offset); 1908 1909 if (!BranchWritePC(context, target)) 1910 return false; 1911 1912 return true; 1913} 1914 1915// This instruction adds a register value and an optionally-shifted register value, and writes the result 1916// to the destination register. It can optionally update the condition flags based on the result. 1917bool 1918EmulateInstructionARM::EmulateADDReg (ARMEncoding encoding) 1919{ 1920#if 0 1921 // ARM pseudo code... 1922 if ConditionPassed() then 1923 EncodingSpecificOperations(); 1924 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1925 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 1926 if d == 15 then 1927 ALUWritePC(result); // setflags is always FALSE here 1928 else 1929 R[d] = result; 1930 if setflags then 1931 APSR.N = result<31>; 1932 APSR.Z = IsZeroBit(result); 1933 APSR.C = carry; 1934 APSR.V = overflow; 1935#endif 1936 1937 bool success = false; 1938 const uint32_t opcode = OpcodeAsUnsigned (&success); 1939 if (!success) 1940 return false; 1941 1942 if (ConditionPassed()) 1943 { 1944 uint32_t Rd, Rn, Rm; 1945 ARM_ShifterType shift_t; 1946 uint32_t shift_n; // the shift applied to the value read from Rm 1947 bool setflags; 1948 switch (encoding) 1949 { 1950 case eEncodingT1: 1951 Rd = Bits32(opcode, 2, 0); 1952 Rn = Bits32(opcode, 5, 3); 1953 Rm = Bits32(opcode, 8, 6); 1954 setflags = !InITBlock(); 1955 shift_t = SRType_LSL; 1956 shift_n = 0; 1957 case eEncodingT2: 1958 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1959 Rm = Bits32(opcode, 6, 3); 1960 setflags = false; 1961 shift_t = SRType_LSL; 1962 shift_n = 0; 1963 if (Rn == 15 && Rm == 15) 1964 return false; 1965 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1966 return false; 1967 break; 1968 default: 1969 return false; 1970 } 1971 1972 int32_t result, val1, val2; 1973 // Read the first operand. 1974 if (Rn == 15) 1975 { 1976 val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1977 if (encoding == eEncodingT1 || encoding == eEncodingT2) 1978 val1 += 4; 1979 else 1980 val1 += 8; 1981 } 1982 else 1983 val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1984 if (!success) 1985 return false; 1986 1987 // Read the second operand. 1988 if (Rm == 15) 1989 { 1990 val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1991 if (encoding == eEncodingT1 || encoding == eEncodingT2) 1992 val1 += 4; 1993 else 1994 val1 += 8; 1995 } 1996 else 1997 val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1998 if (!success) 1999 return false; 2000 2001 val2 = Shift(val2, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C)); 2002 AddWithCarryResult res = AddWithCarry(val1, val2, 0); 2003 result = val1 + val2; 2004 2005 EmulateInstruction::Context context; 2006 context.type = EmulateInstruction::eContextImmediate; 2007 context.SetNoArgs (); 2008 2009 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2010 return false; 2011 } 2012 return true; 2013} 2014 2015// CMP (immediate) 2016bool 2017EmulateInstructionARM::EmulateCMPRnImm (ARMEncoding encoding) 2018{ 2019#if 0 2020 // ARM pseudo code... 2021 if ConditionPassed() then 2022 EncodingSpecificOperations(); 2023 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2024 APSR.N = result<31>; 2025 APSR.Z = IsZeroBit(result); 2026 APSR.C = carry; 2027 APSR.V = overflow; 2028#endif 2029 2030 bool success = false; 2031 const uint32_t opcode = OpcodeAsUnsigned (&success); 2032 if (!success) 2033 return false; 2034 2035 uint32_t Rn; // the first operand 2036 uint32_t imm32; // the immediate value to be compared with 2037 switch (encoding) { 2038 case eEncodingT1: 2039 Rn = Bits32(opcode, 10, 8); 2040 imm32 = Bits32(opcode, 7, 0); 2041 break; 2042 default: 2043 return false; 2044 } 2045 // Read the register value from the operand register Rn. 2046 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2047 if (!success) 2048 return false; 2049 2050 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2051 2052 EmulateInstruction::Context context; 2053 context.type = EmulateInstruction::eContextImmediate; 2054 context.SetNoArgs (); 2055 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2056 return false; 2057 2058 return true; 2059} 2060 2061// CMP (register) 2062bool 2063EmulateInstructionARM::EmulateCMPRnRm (ARMEncoding encoding) 2064{ 2065#if 0 2066 // ARM pseudo code... 2067 if ConditionPassed() then 2068 EncodingSpecificOperations(); 2069 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2070 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2071 APSR.N = result<31>; 2072 APSR.Z = IsZeroBit(result); 2073 APSR.C = carry; 2074 APSR.V = overflow; 2075#endif 2076 2077 bool success = false; 2078 const uint32_t opcode = OpcodeAsUnsigned (&success); 2079 if (!success) 2080 return false; 2081 2082 uint32_t Rn; // the first operand 2083 uint32_t Rm; // the second operand 2084 switch (encoding) { 2085 case eEncodingT1: 2086 Rn = Bits32(opcode, 2, 0); 2087 Rm = Bits32(opcode, 5, 3); 2088 break; 2089 case eEncodingT2: 2090 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2091 Rm = Bits32(opcode, 6, 3); 2092 if (Rn < 8 && Rm < 8) 2093 return false; 2094 if (Rn == 15 || Rm == 15) 2095 return false; 2096 break; 2097 default: 2098 return false; 2099 } 2100 // Read the register value from register Rn. 2101 uint32_t reg_val1 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2102 if (!success) 2103 return false; 2104 // Read the register value from register Rm. 2105 // The register value is not being shifted since we don't handle ARM for now. 2106 uint32_t reg_val2 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2107 if (!success) 2108 return false; 2109 2110 AddWithCarryResult res = AddWithCarry(reg_val1, ~reg_val2, 1); 2111 2112 EmulateInstruction::Context context; 2113 context.type = EmulateInstruction::eContextImmediate; 2114 context.SetNoArgs(); 2115 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2116 return false; 2117 2118 return true; 2119} 2120 2121// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2122// shifting in copies of its sign bit, and writes the result to the destination register. It can 2123// optionally update the condition flags based on the result. 2124bool 2125EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding) 2126{ 2127#if 0 2128 // ARM pseudo code... 2129 if ConditionPassed() then 2130 EncodingSpecificOperations(); 2131 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2132 if d == 15 then // Can only occur for ARM encoding 2133 ALUWritePC(result); // setflags is always FALSE here 2134 else 2135 R[d] = result; 2136 if setflags then 2137 APSR.N = result<31>; 2138 APSR.Z = IsZeroBit(result); 2139 APSR.C = carry; 2140 // APSR.V unchanged 2141#endif 2142 2143 return EmulateShiftImm(encoding, SRType_ASR); 2144} 2145 2146// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2147// shifting in copies of its sign bit, and writes the result to the destination register. 2148// The variable number of bits is read from the bottom byte of a register. It can optionally update 2149// the condition flags based on the result. 2150bool 2151EmulateInstructionARM::EmulateASRReg (ARMEncoding encoding) 2152{ 2153#if 0 2154 // ARM pseudo code... 2155 if ConditionPassed() then 2156 EncodingSpecificOperations(); 2157 shift_n = UInt(R[m]<7:0>); 2158 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2159 R[d] = result; 2160 if setflags then 2161 APSR.N = result<31>; 2162 APSR.Z = IsZeroBit(result); 2163 APSR.C = carry; 2164 // APSR.V unchanged 2165#endif 2166 2167 return EmulateShiftReg(encoding, SRType_ASR); 2168} 2169 2170// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2171// shifting in zeros, and writes the result to the destination register. It can optionally 2172// update the condition flags based on the result. 2173bool 2174EmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding) 2175{ 2176#if 0 2177 // ARM pseudo code... 2178 if ConditionPassed() then 2179 EncodingSpecificOperations(); 2180 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2181 if d == 15 then // Can only occur for ARM encoding 2182 ALUWritePC(result); // setflags is always FALSE here 2183 else 2184 R[d] = result; 2185 if setflags then 2186 APSR.N = result<31>; 2187 APSR.Z = IsZeroBit(result); 2188 APSR.C = carry; 2189 // APSR.V unchanged 2190#endif 2191 2192 return EmulateShiftImm(encoding, SRType_LSL); 2193} 2194 2195// Logical Shift Left (register) shifts a register value left by a variable number of bits, 2196// shifting in zeros, and writes the result to the destination register. The variable number 2197// of bits is read from the bottom byte of a register. It can optionally update the condition 2198// flags based on the result. 2199bool 2200EmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding) 2201{ 2202#if 0 2203 // ARM pseudo code... 2204 if ConditionPassed() then 2205 EncodingSpecificOperations(); 2206 shift_n = UInt(R[m]<7:0>); 2207 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2208 R[d] = result; 2209 if setflags then 2210 APSR.N = result<31>; 2211 APSR.Z = IsZeroBit(result); 2212 APSR.C = carry; 2213 // APSR.V unchanged 2214#endif 2215 2216 return EmulateShiftReg(encoding, SRType_LSL); 2217} 2218 2219// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 2220// shifting in zeros, and writes the result to the destination register. It can optionally 2221// update the condition flags based on the result. 2222bool 2223EmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding) 2224{ 2225#if 0 2226 // ARM pseudo code... 2227 if ConditionPassed() then 2228 EncodingSpecificOperations(); 2229 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 2230 if d == 15 then // Can only occur for ARM encoding 2231 ALUWritePC(result); // setflags is always FALSE here 2232 else 2233 R[d] = result; 2234 if setflags then 2235 APSR.N = result<31>; 2236 APSR.Z = IsZeroBit(result); 2237 APSR.C = carry; 2238 // APSR.V unchanged 2239#endif 2240 2241 return EmulateShiftImm(encoding, SRType_LSR); 2242} 2243 2244// Logical Shift Right (register) shifts a register value right by a variable number of bits, 2245// shifting in zeros, and writes the result to the destination register. The variable number 2246// of bits is read from the bottom byte of a register. It can optionally update the condition 2247// flags based on the result. 2248bool 2249EmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding) 2250{ 2251#if 0 2252 // ARM pseudo code... 2253 if ConditionPassed() then 2254 EncodingSpecificOperations(); 2255 shift_n = UInt(R[m]<7:0>); 2256 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 2257 R[d] = result; 2258 if setflags then 2259 APSR.N = result<31>; 2260 APSR.Z = IsZeroBit(result); 2261 APSR.C = carry; 2262 // APSR.V unchanged 2263#endif 2264 2265 return EmulateShiftReg(encoding, SRType_LSR); 2266} 2267 2268// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 2269// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2270// It can optionally update the condition flags based on the result. 2271bool 2272EmulateInstructionARM::EmulateRORImm (ARMEncoding encoding) 2273{ 2274#if 0 2275 // ARM pseudo code... 2276 if ConditionPassed() then 2277 EncodingSpecificOperations(); 2278 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2279 if d == 15 then // Can only occur for ARM encoding 2280 ALUWritePC(result); // setflags is always FALSE here 2281 else 2282 R[d] = result; 2283 if setflags then 2284 APSR.N = result<31>; 2285 APSR.Z = IsZeroBit(result); 2286 APSR.C = carry; 2287 // APSR.V unchanged 2288#endif 2289 2290 return EmulateShiftImm(encoding, SRType_ROR); 2291} 2292 2293// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 2294// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2295// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 2296// flags based on the result. 2297bool 2298EmulateInstructionARM::EmulateRORReg (ARMEncoding encoding) 2299{ 2300#if 0 2301 // ARM pseudo code... 2302 if ConditionPassed() then 2303 EncodingSpecificOperations(); 2304 shift_n = UInt(R[m]<7:0>); 2305 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2306 R[d] = result; 2307 if setflags then 2308 APSR.N = result<31>; 2309 APSR.Z = IsZeroBit(result); 2310 APSR.C = carry; 2311 // APSR.V unchanged 2312#endif 2313 2314 return EmulateShiftReg(encoding, SRType_ROR); 2315} 2316 2317// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 2318// with the carry flag shifted into bit [31]. 2319// 2320// RRX can optionally update the condition flags based on the result. 2321// In that case, bit [0] is shifted into the carry flag. 2322bool 2323EmulateInstructionARM::EmulateRRX (ARMEncoding encoding) 2324{ 2325#if 0 2326 // ARM pseudo code... 2327 if ConditionPassed() then 2328 EncodingSpecificOperations(); 2329 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 2330 if d == 15 then // Can only occur for ARM encoding 2331 ALUWritePC(result); // setflags is always FALSE here 2332 else 2333 R[d] = result; 2334 if setflags then 2335 APSR.N = result<31>; 2336 APSR.Z = IsZeroBit(result); 2337 APSR.C = carry; 2338 // APSR.V unchanged 2339#endif 2340 2341 return EmulateShiftImm(encoding, SRType_RRX); 2342} 2343 2344bool 2345EmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type) 2346{ 2347 assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 2348 2349 bool success = false; 2350 const uint32_t opcode = OpcodeAsUnsigned (&success); 2351 if (!success) 2352 return false; 2353 2354 if (ConditionPassed()) 2355 { 2356 uint32_t Rd; // the destination register 2357 uint32_t Rm; // the first operand register 2358 uint32_t imm5; // encoding for the shift amount 2359 uint32_t carry; // the carry bit after the shift operation 2360 bool setflags; 2361 2362 // Special case handling! 2363 // A8.6.139 ROR (immediate) -- Encoding T1 2364 if (shift_type == SRType_ROR && encoding == eEncodingT1) 2365 { 2366 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 2367 // have the same decoding of bit fields as the other Thumb2 shift operations. 2368 encoding = eEncodingT2; 2369 } 2370 2371 switch (encoding) { 2372 case eEncodingT1: 2373 // Due to the above special case handling! 2374 assert(shift_type != SRType_ROR); 2375 2376 Rd = Bits32(opcode, 2, 0); 2377 Rm = Bits32(opcode, 5, 3); 2378 setflags = !InITBlock(); 2379 imm5 = Bits32(opcode, 10, 6); 2380 break; 2381 case eEncodingT2: 2382 // A8.6.141 RRX 2383 assert(shift_type != SRType_RRX); 2384 2385 Rd = Bits32(opcode, 11, 8); 2386 Rm = Bits32(opcode, 3, 0); 2387 setflags = BitIsSet(opcode, 20); 2388 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 2389 if (BadReg(Rd) || BadReg(Rm)) 2390 return false; 2391 break; 2392 case eEncodingA1: 2393 Rd = Bits32(opcode, 15, 12); 2394 Rm = Bits32(opcode, 3, 0); 2395 setflags = BitIsSet(opcode, 20); 2396 imm5 = Bits32(opcode, 11, 7); 2397 break; 2398 default: 2399 return false; 2400 } 2401 2402 // A8.6.139 ROR (immediate) 2403 if (shift_type == SRType_ROR && imm5 == 0) 2404 shift_type = SRType_RRX; 2405 2406 // Get the first operand. 2407 uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2408 if (!success) 2409 return false; 2410 2411 // Decode the shift amount if not RRX. 2412 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 2413 2414 uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry); 2415 2416 // The context specifies that an immediate is to be moved into Rd. 2417 EmulateInstruction::Context context; 2418 context.type = EmulateInstruction::eContextImmediate; 2419 context.SetNoArgs (); 2420 2421 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2422 return false; 2423 } 2424 return true; 2425} 2426 2427bool 2428EmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type) 2429{ 2430 assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 2431 2432 bool success = false; 2433 const uint32_t opcode = OpcodeAsUnsigned (&success); 2434 if (!success) 2435 return false; 2436 2437 if (ConditionPassed()) 2438 { 2439 uint32_t Rd; // the destination register 2440 uint32_t Rn; // the first operand register 2441 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 2442 uint32_t carry; // the carry bit after the shift operation 2443 bool setflags; 2444 switch (encoding) { 2445 case eEncodingT1: 2446 Rd = Bits32(opcode, 2, 0); 2447 Rn = Rd; 2448 Rm = Bits32(opcode, 5, 3); 2449 setflags = !InITBlock(); 2450 break; 2451 case eEncodingT2: 2452 Rd = Bits32(opcode, 11, 8); 2453 Rn = Bits32(opcode, 19, 16); 2454 Rm = Bits32(opcode, 3, 0); 2455 setflags = BitIsSet(opcode, 20); 2456 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 2457 return false; 2458 break; 2459 case eEncodingA1: 2460 Rd = Bits32(opcode, 15, 12); 2461 Rn = Bits32(opcode, 3, 0); 2462 Rm = Bits32(opcode, 11, 8); 2463 setflags = BitIsSet(opcode, 20); 2464 if (Rd == 15 || Rn == 15 || Rm == 15) 2465 return false; 2466 break; 2467 default: 2468 return false; 2469 } 2470 2471 // Get the first operand. 2472 uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2473 if (!success) 2474 return false; 2475 // Get the Rm register content. 2476 uint32_t val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2477 if (!success) 2478 return false; 2479 2480 // Get the shift amount. 2481 uint32_t amt = Bits32(val, 7, 0); 2482 2483 uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry); 2484 2485 // The context specifies that an immediate is to be moved into Rd. 2486 EmulateInstruction::Context context; 2487 context.type = EmulateInstruction::eContextImmediate; 2488 context.SetNoArgs (); 2489 2490 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2491 return false; 2492 } 2493 return true; 2494} 2495 2496// LDM loads multiple registers from consecutive memory locations, using an 2497// address from a base register. Optionally the address just above the highest of those locations 2498// can be written back to the base register. 2499bool 2500EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 2501{ 2502#if 0 2503 // ARM pseudo code... 2504 if ConditionPassed() 2505 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 2506 address = R[n]; 2507 2508 for i = 0 to 14 2509 if registers<i> == '1' then 2510 R[i] = MemA[address, 4]; address = address + 4; 2511 if registers<15> == '1' then 2512 LoadWritePC (MemA[address, 4]); 2513 2514 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 2515 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2516 2517#endif 2518 2519 bool success = false; 2520 const uint32_t opcode = OpcodeAsUnsigned (&success); 2521 if (!success) 2522 return false; 2523 2524 if (ConditionPassed()) 2525 { 2526 uint32_t n; 2527 uint32_t registers = 0; 2528 bool wback; 2529 const uint32_t addr_byte_size = GetAddressByteSize(); 2530 switch (encoding) 2531 { 2532 case eEncodingT1: 2533 // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’); 2534 n = Bits32 (opcode, 10, 8); 2535 registers = Bits32 (opcode, 7, 0); 2536 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2537 wback = BitIsClear (registers, n); 2538 // if BitCount(registers) < 1 then UNPREDICTABLE; 2539 if (BitCount(registers) < 1) 2540 return false; 2541 break; 2542 case eEncodingT2: 2543 // if W == ’1’ && Rn == ’1101’ then SEE POP; 2544 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2545 n = Bits32 (opcode, 19, 16); 2546 registers = Bits32 (opcode, 15, 0); 2547 registers = registers & 0xdfff; // Make sure bit 13 is zero. 2548 wback = BitIsSet (opcode, 21); 2549 2550 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2551 if ((n == 15) 2552 || (BitCount (registers) < 2) 2553 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2554 return false; 2555 2556 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2557 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2558 return false; 2559 2560 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2561 if (wback 2562 && BitIsSet (registers, n)) 2563 return false; 2564 break; 2565 2566 case eEncodingA1: 2567 n = Bits32 (opcode, 19, 16); 2568 registers = Bits32 (opcode, 15, 0); 2569 wback = BitIsSet (opcode, 21); 2570 if ((n == 15) 2571 || (BitCount (registers) < 1)) 2572 return false; 2573 break; 2574 default: 2575 return false; 2576 } 2577 2578 int32_t offset = 0; 2579 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2580 if (!success) 2581 return false; 2582 2583 EmulateInstruction::Context context; 2584 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2585 Register dwarf_reg; 2586 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2587 context.SetRegisterPlusOffset (dwarf_reg, offset); 2588 2589 for (int i = 0; i < 14; ++i) 2590 { 2591 if (BitIsSet (registers, i)) 2592 { 2593 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2594 context.SetRegisterPlusOffset (dwarf_reg, offset); 2595 if (wback && (n == 13)) // Pop Instruction 2596 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2597 2598 // R[i] = MemA [address, 4]; address = address + 4; 2599 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 2600 if (!success) 2601 return false; 2602 2603 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2604 return false; 2605 2606 offset += addr_byte_size; 2607 } 2608 } 2609 2610 if (BitIsSet (registers, 15)) 2611 { 2612 //LoadWritePC (MemA [address, 4]); 2613 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2614 context.SetRegisterPlusOffset (dwarf_reg, offset); 2615 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 2616 if (!success) 2617 return false; 2618 // In ARMv5T and above, this is an interworking branch. 2619 if (!LoadWritePC(context, data)) 2620 return false; 2621 } 2622 2623 if (wback && BitIsClear (registers, n)) 2624 { 2625 // R[n] = R[n] + 4 * BitCount (registers) 2626 int32_t offset = addr_byte_size * BitCount (registers); 2627 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2628 context.SetRegisterPlusOffset (dwarf_reg, offset); 2629 2630 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 2631 return false; 2632 } 2633 if (wback && BitIsSet (registers, n)) 2634 // R[n] bits(32) UNKNOWN; 2635 return WriteBits32Unknown (n); 2636 } 2637 return true; 2638} 2639 2640// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers. 2641// The consecutive memorty locations end at this address and the address just below the lowest of those locations 2642// can optionally be written back tot he base registers. 2643bool 2644EmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding) 2645{ 2646#if 0 2647 // ARM pseudo code... 2648 if ConditionPassed() then 2649 EncodingSpecificOperations(); 2650 address = R[n] - 4*BitCount(registers) + 4; 2651 2652 for i = 0 to 14 2653 if registers<i> == ’1’ then 2654 R[i] = MemA[address,4]; address = address + 4; 2655 2656 if registers<15> == ’1’ then 2657 LoadWritePC(MemA[address,4]); 2658 2659 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2660 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2661#endif 2662 2663 bool success = false; 2664 const uint32_t opcode = OpcodeAsUnsigned (&success); 2665 if (!success) 2666 return false; 2667 2668 if (ConditionPassed()) 2669 { 2670 uint32_t n; 2671 uint32_t registers = 0; 2672 bool wback; 2673 const uint32_t addr_byte_size = GetAddressByteSize(); 2674 2675 // EncodingSpecificOperations(); 2676 switch (encoding) 2677 { 2678 case eEncodingA1: 2679 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2680 n = Bits32 (opcode, 19, 16); 2681 registers = Bits32 (opcode, 15, 0); 2682 wback = BitIsSet (opcode, 21); 2683 2684 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2685 if ((n == 15) || (BitCount (registers) < 1)) 2686 return false; 2687 2688 break; 2689 2690 default: 2691 return false; 2692 } 2693 // address = R[n] - 4*BitCount(registers) + 4; 2694 2695 int32_t offset = 0; 2696 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2697 2698 if (!success) 2699 return false; 2700 2701 address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size; 2702 2703 EmulateInstruction::Context context; 2704 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2705 Register dwarf_reg; 2706 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2707 context.SetRegisterPlusOffset (dwarf_reg, offset); 2708 2709 // for i = 0 to 14 2710 for (int i = 0; i < 14; ++i) 2711 { 2712 // if registers<i> == ’1’ then 2713 if (BitIsSet (registers, i)) 2714 { 2715 // R[i] = MemA[address,4]; address = address + 4; 2716 context.SetRegisterPlusOffset (dwarf_reg, offset); 2717 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 2718 if (!success) 2719 return false; 2720 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2721 return false; 2722 offset += addr_byte_size; 2723 } 2724 } 2725 2726 // if registers<15> == ’1’ then 2727 // LoadWritePC(MemA[address,4]); 2728 if (BitIsSet (registers, 15)) 2729 { 2730 context.SetRegisterPlusOffset (dwarf_reg, offset); 2731 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 2732 if (!success) 2733 return false; 2734 // In ARMv5T and above, this is an interworking branch. 2735 if (!LoadWritePC(context, data)) 2736 return false; 2737 } 2738 2739 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2740 if (wback && BitIsClear (registers, n)) 2741 { 2742 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2743 if (!success) 2744 return false; 2745 2746 offset = (addr_byte_size * BitCount (registers)) * -1; 2747 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2748 context.SetImmediateSigned (offset); 2749 addr = addr + offset; 2750 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2751 return false; 2752 } 2753 2754 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2755 if (wback && BitIsSet (registers, n)) 2756 return WriteBits32Unknown (n); 2757 } 2758 return true; 2759} 2760 2761// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 2762// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 2763// be optionally written back to the base register. 2764bool 2765EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 2766{ 2767#if 0 2768 // ARM pseudo code... 2769 if ConditionPassed() then 2770 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2771 address = R[n] - 4*BitCount(registers); 2772 2773 for i = 0 to 14 2774 if registers<i> == ’1’ then 2775 R[i] = MemA[address,4]; address = address + 4; 2776 if registers<15> == ’1’ then 2777 LoadWritePC(MemA[address,4]); 2778 2779 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2780 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2781#endif 2782 2783 bool success = false; 2784 const uint32_t opcode = OpcodeAsUnsigned (&success); 2785 if (!success) 2786 return false; 2787 2788 if (ConditionPassed()) 2789 { 2790 uint32_t n; 2791 uint32_t registers = 0; 2792 bool wback; 2793 const uint32_t addr_byte_size = GetAddressByteSize(); 2794 switch (encoding) 2795 { 2796 case eEncodingT1: 2797 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2798 n = Bits32 (opcode, 19, 16); 2799 registers = Bits32 (opcode, 15, 0); 2800 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 2801 wback = BitIsSet (opcode, 21); 2802 2803 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2804 if ((n == 15) 2805 || (BitCount (registers) < 2) 2806 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2807 return false; 2808 2809 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2810 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2811 return false; 2812 2813 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2814 if (wback && BitIsSet (registers, n)) 2815 return false; 2816 2817 break; 2818 2819 case eEncodingA1: 2820 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2821 n = Bits32 (opcode, 19, 16); 2822 registers = Bits32 (opcode, 15, 0); 2823 wback = BitIsSet (opcode, 21); 2824 2825 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2826 if ((n == 15) || (BitCount (registers) < 1)) 2827 return false; 2828 2829 break; 2830 2831 default: 2832 return false; 2833 } 2834 2835 // address = R[n] - 4*BitCount(registers); 2836 2837 int32_t offset = 0; 2838 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2839 2840 if (!success) 2841 return false; 2842 2843 address = address - (addr_byte_size * BitCount (registers)); 2844 EmulateInstruction::Context context; 2845 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2846 Register dwarf_reg; 2847 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2848 context.SetRegisterPlusOffset (dwarf_reg, offset); 2849 2850 for (int i = 0; i < 14; ++i) 2851 { 2852 if (BitIsSet (registers, i)) 2853 { 2854 // R[i] = MemA[address,4]; address = address + 4; 2855 context.SetRegisterPlusOffset (dwarf_reg, offset); 2856 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 2857 if (!success) 2858 return false; 2859 2860 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2861 return false; 2862 2863 offset += addr_byte_size; 2864 } 2865 } 2866 2867 // if registers<15> == ’1’ then 2868 // LoadWritePC(MemA[address,4]); 2869 if (BitIsSet (registers, 15)) 2870 { 2871 context.SetRegisterPlusOffset (dwarf_reg, offset); 2872 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 2873 if (!success) 2874 return false; 2875 // In ARMv5T and above, this is an interworking branch. 2876 if (!LoadWritePC(context, data)) 2877 return false; 2878 } 2879 2880 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2881 if (wback && BitIsClear (registers, n)) 2882 { 2883 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2884 if (!success) 2885 return false; 2886 2887 offset = (addr_byte_size * BitCount (registers)) * -1; 2888 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2889 context.SetImmediateSigned (offset); 2890 addr = addr + offset; 2891 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2892 return false; 2893 } 2894 2895 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2896 if (wback && BitIsSet (registers, n)) 2897 return WriteBits32Unknown (n); 2898 } 2899 return true; 2900} 2901 2902// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 2903// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 2904// optinoally be written back to the base register. 2905bool 2906EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 2907{ 2908#if 0 2909 if ConditionPassed() then 2910 EncodingSpecificOperations(); 2911 address = R[n] + 4; 2912 2913 for i = 0 to 14 2914 if registers<i> == ’1’ then 2915 R[i] = MemA[address,4]; address = address + 4; 2916 if registers<15> == ’1’ then 2917 LoadWritePC(MemA[address,4]); 2918 2919 if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2920 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2921#endif 2922 2923 bool success = false; 2924 const uint32_t opcode = OpcodeAsUnsigned (&success); 2925 if (!success) 2926 return false; 2927 2928 if (ConditionPassed()) 2929 { 2930 uint32_t n; 2931 uint32_t registers = 0; 2932 bool wback; 2933 const uint32_t addr_byte_size = GetAddressByteSize(); 2934 switch (encoding) 2935 { 2936 case eEncodingA1: 2937 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2938 n = Bits32 (opcode, 19, 16); 2939 registers = Bits32 (opcode, 15, 0); 2940 wback = BitIsSet (opcode, 21); 2941 2942 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2943 if ((n == 15) || (BitCount (registers) < 1)) 2944 return false; 2945 2946 break; 2947 default: 2948 return false; 2949 } 2950 // address = R[n] + 4; 2951 2952 int32_t offset = 0; 2953 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2954 2955 if (!success) 2956 return false; 2957 2958 address = address + addr_byte_size; 2959 2960 EmulateInstruction::Context context; 2961 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2962 Register dwarf_reg; 2963 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2964 context.SetRegisterPlusOffset (dwarf_reg, offset); 2965 2966 for (int i = 0; i < 14; ++i) 2967 { 2968 if (BitIsSet (registers, i)) 2969 { 2970 // R[i] = MemA[address,4]; address = address + 4; 2971 2972 context.SetRegisterPlusOffset (dwarf_reg, offset); 2973 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 2974 if (!success) 2975 return false; 2976 2977 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2978 return false; 2979 2980 offset += addr_byte_size; 2981 } 2982 } 2983 2984 // if registers<15> == ’1’ then 2985 // LoadWritePC(MemA[address,4]); 2986 if (BitIsSet (registers, 15)) 2987 { 2988 context.SetRegisterPlusOffset (dwarf_reg, offset); 2989 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 2990 if (!success) 2991 return false; 2992 // In ARMv5T and above, this is an interworking branch. 2993 if (!LoadWritePC(context, data)) 2994 return false; 2995 } 2996 2997 // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2998 if (wback && BitIsClear (registers, n)) 2999 { 3000 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3001 if (!success) 3002 return false; 3003 3004 offset = addr_byte_size * BitCount (registers); 3005 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3006 context.SetImmediateSigned (offset); 3007 addr = addr + offset; 3008 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3009 return false; 3010 } 3011 3012 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3013 if (wback && BitIsSet (registers, n)) 3014 return WriteBits32Unknown (n); 3015 } 3016 return true; 3017} 3018 3019// Load Register (immediate) calculates an address from a base register value and 3020// an immediate offset, loads a word from memory, and writes to a register. 3021// LDR (immediate, Thumb) 3022bool 3023EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 3024{ 3025#if 0 3026 // ARM pseudo code... 3027 if (ConditionPassed()) 3028 { 3029 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3030 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3031 address = if index then offset_addr else R[n]; 3032 data = MemU[address,4]; 3033 if wback then R[n] = offset_addr; 3034 if t == 15 then 3035 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3036 elsif UnalignedSupport() || address<1:0> = '00' then 3037 R[t] = data; 3038 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3039 } 3040#endif 3041 3042 bool success = false; 3043 const uint32_t opcode = OpcodeAsUnsigned (&success); 3044 if (!success) 3045 return false; 3046 3047 if (ConditionPassed()) 3048 { 3049 uint32_t Rt; // the destination register 3050 uint32_t Rn; // the base register 3051 uint32_t imm32; // the immediate offset used to form the address 3052 addr_t offset_addr; // the offset address 3053 addr_t address; // the calculated address 3054 uint32_t data; // the literal data value from memory load 3055 bool add, index, wback; 3056 switch (encoding) { 3057 case eEncodingT1: 3058 Rt = Bits32(opcode, 5, 3); 3059 Rn = Bits32(opcode, 2, 0); 3060 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3061 // index = TRUE; add = TRUE; wback = FALSE 3062 add = true; 3063 index = true; 3064 wback = false; 3065 break; 3066 default: 3067 return false; 3068 } 3069 uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 3070 if (!success) 3071 return false; 3072 if (add) 3073 offset_addr = base + imm32; 3074 else 3075 offset_addr = base - imm32; 3076 3077 address = (index ? offset_addr : base); 3078 3079 if (wback) 3080 { 3081 EmulateInstruction::Context ctx; 3082 ctx.type = EmulateInstruction::eContextRegisterPlusOffset; 3083 Register dwarf_reg; 3084 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 3085 ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base)); 3086 3087 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3088 return false; 3089 } 3090 3091 // Prepare to write to the Rt register. 3092 EmulateInstruction::Context context; 3093 context.type = EmulateInstruction::eContextImmediate; 3094 context.SetNoArgs (); 3095 3096 // Read memory from the address. 3097 data = MemURead(context, address, 4, 0, &success); 3098 if (!success) 3099 return false; 3100 3101 if (Rt == 15) 3102 { 3103 if (Bits32(address, 1, 0) == 0) 3104 { 3105 if (!LoadWritePC(context, data)) 3106 return false; 3107 } 3108 else 3109 return false; 3110 } 3111 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3112 { 3113 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3114 return false; 3115 } 3116 else 3117 return false; 3118 } 3119 return true; 3120} 3121 3122// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3123// from a base register. The consecutive memory locations start at this address, and teh address just above the last 3124// of those locations can optionally be written back to the base register. 3125bool 3126EmulateInstructionARM::EmulateSTM (ARMEncoding encoding) 3127{ 3128#if 0 3129 if ConditionPassed() then 3130 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3131 address = R[n]; 3132 3133 for i = 0 to 14 3134 if registers<i> == ’1’ then 3135 if i == n && wback && i != LowestSetBit(registers) then 3136 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3137 else 3138 MemA[address,4] = R[i]; 3139 address = address + 4; 3140 3141 if registers<15> == ’1’ then // Only possible for encoding A1 3142 MemA[address,4] = PCStoreValue(); 3143 if wback then R[n] = R[n] + 4*BitCount(registers); 3144#endif 3145 3146 bool success = false; 3147 const uint32_t opcode = OpcodeAsUnsigned (&success); 3148 if (!success) 3149 return false; 3150 3151 if (ConditionPassed ()) 3152 { 3153 uint32_t n; 3154 uint32_t registers = 0; 3155 bool wback; 3156 const uint32_t addr_byte_size = GetAddressByteSize(); 3157 3158 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3159 switch (encoding) 3160 { 3161 case eEncodingT1: 3162 // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE; 3163 n = Bits32 (opcode, 10, 8); 3164 registers = Bits32 (opcode, 7, 0); 3165 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3166 wback = true; 3167 3168 // if BitCount(registers) < 1 then UNPREDICTABLE; 3169 if (BitCount (registers) < 1) 3170 return false; 3171 3172 break; 3173 3174 case eEncodingT2: 3175 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3176 n = Bits32 (opcode, 19, 16); 3177 registers = Bits32 (opcode, 15, 0); 3178 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3179 wback = BitIsSet (opcode, 21); 3180 3181 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3182 if ((n == 15) || (BitCount (registers) < 2)) 3183 return false; 3184 3185 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3186 if (wback && BitIsSet (registers, n)) 3187 return false; 3188 3189 break; 3190 3191 case eEncodingA1: 3192 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3193 n = Bits32 (opcode, 19, 16); 3194 registers = Bits32 (opcode, 15, 0); 3195 wback = BitIsSet (opcode, 21); 3196 3197 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3198 if ((n == 15) || (BitCount (registers) < 1)) 3199 return false; 3200 3201 break; 3202 3203 default: 3204 return false; 3205 } 3206 3207 // address = R[n]; 3208 int32_t offset = 0; 3209 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3210 if (!success) 3211 return false; 3212 3213 EmulateInstruction::Context context; 3214 context.type = EmulateInstruction::eContextRegisterStore; 3215 Register base_reg; 3216 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3217 3218 // for i = 0 to 14 3219 for (int i = 0; i < 14; ++i) 3220 { 3221 int lowest_set_bit = 14; 3222 // if registers<i> == ’1’ then 3223 if (BitIsSet (registers, i)) 3224 { 3225 if (i < lowest_set_bit) 3226 lowest_set_bit = i; 3227 // if i == n && wback && i != LowestSetBit(registers) then 3228 if ((i == n) && wback && (i != lowest_set_bit)) 3229 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3230 WriteBits32UnknownToMemory (address + offset); 3231 else 3232 { 3233 // MemA[address,4] = R[i]; 3234 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3235 if (!success) 3236 return false; 3237 3238 Register data_reg; 3239 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3240 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3241 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3242 return false; 3243 } 3244 3245 // address = address + 4; 3246 offset += addr_byte_size; 3247 } 3248 } 3249 3250 // if registers<15> == ’1’ then // Only possible for encoding A1 3251 // MemA[address,4] = PCStoreValue(); 3252 if (BitIsSet (registers, 15)) 3253 { 3254 Register pc_reg; 3255 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3256 context.SetRegisterPlusOffset (pc_reg, 8); 3257 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3258 if (!success) 3259 return false; 3260 3261 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3262 return false; 3263 } 3264 3265 // if wback then R[n] = R[n] + 4*BitCount(registers); 3266 if (wback) 3267 { 3268 offset = addr_byte_size * BitCount (registers); 3269 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3270 context.SetImmediateSigned (offset); 3271 addr_t data = address + offset; 3272 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3273 return false; 3274 } 3275 } 3276 return true; 3277} 3278 3279// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 3280// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3281// of those locations can optionally be written back to the base register. 3282bool 3283EmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding) 3284{ 3285#if 0 3286 if ConditionPassed() then 3287 EncodingSpecificOperations(); 3288 address = R[n] - 4*BitCount(registers) + 4; 3289 3290 for i = 0 to 14 3291 if registers<i> == ’1’ then 3292 if i == n && wback && i != LowestSetBit(registers) then 3293 MemA[address,4] = bits(32) UNKNOWN; 3294 else 3295 MemA[address,4] = R[i]; 3296 address = address + 4; 3297 3298 if registers<15> == ’1’ then 3299 MemA[address,4] = PCStoreValue(); 3300 3301 if wback then R[n] = R[n] - 4*BitCount(registers); 3302#endif 3303 3304 bool success = false; 3305 const uint32_t opcode = OpcodeAsUnsigned (&success); 3306 if (!success) 3307 return false; 3308 3309 if (ConditionPassed ()) 3310 { 3311 uint32_t n; 3312 uint32_t registers = 0; 3313 bool wback; 3314 const uint32_t addr_byte_size = GetAddressByteSize(); 3315 3316 // EncodingSpecificOperations(); 3317 switch (encoding) 3318 { 3319 case eEncodingA1: 3320 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3321 n = Bits32 (opcode, 19, 16); 3322 registers = Bits32 (opcode, 15, 0); 3323 wback = BitIsSet (opcode, 21); 3324 3325 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3326 if ((n == 15) || (BitCount (registers) < 1)) 3327 return false; 3328 break; 3329 default: 3330 return false; 3331 } 3332 3333 // address = R[n] - 4*BitCount(registers) + 4; 3334 int32_t offset = 0; 3335 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3336 if (!success) 3337 return false; 3338 3339 address = address - (addr_byte_size * BitCount (registers)) + 4; 3340 3341 EmulateInstruction::Context context; 3342 context.type = EmulateInstruction::eContextRegisterStore; 3343 Register base_reg; 3344 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3345 3346 // for i = 0 to 14 3347 for (int i = 0; i < 14; ++i) 3348 { 3349 int lowest_bit_set = 14; 3350 // if registers<i> == ’1’ then 3351 if (BitIsSet (registers, i)) 3352 { 3353 if (i < lowest_bit_set) 3354 lowest_bit_set = i; 3355 //if i == n && wback && i != LowestSetBit(registers) then 3356 if ((i == n) && wback && (i != lowest_bit_set)) 3357 // MemA[address,4] = bits(32) UNKNOWN; 3358 WriteBits32UnknownToMemory (address + offset); 3359 else 3360 { 3361 // MemA[address,4] = R[i]; 3362 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3363 if (!success) 3364 return false; 3365 3366 Register data_reg; 3367 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3368 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3369 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3370 return false; 3371 } 3372 3373 // address = address + 4; 3374 offset += addr_byte_size; 3375 } 3376 } 3377 3378 // if registers<15> == ’1’ then 3379 // MemA[address,4] = PCStoreValue(); 3380 if (BitIsSet (registers, 15)) 3381 { 3382 Register pc_reg; 3383 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3384 context.SetRegisterPlusOffset (pc_reg, 8); 3385 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3386 if (!success) 3387 return false; 3388 3389 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3390 return false; 3391 } 3392 3393 // if wback then R[n] = R[n] - 4*BitCount(registers); 3394 if (wback) 3395 { 3396 offset = (addr_byte_size * BitCount (registers)) * -1; 3397 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3398 context.SetImmediateSigned (offset); 3399 addr_t data = address + offset; 3400 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3401 return false; 3402 } 3403 } 3404 return true; 3405} 3406 3407// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 3408// from a base register. The consecutive memory locations end just below this address, and the address of the first of 3409// those locations can optionally be written back to the base register. 3410bool 3411EmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding) 3412{ 3413#if 0 3414 if ConditionPassed() then 3415 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3416 address = R[n] - 4*BitCount(registers); 3417 3418 for i = 0 to 14 3419 if registers<i> == ’1’ then 3420 if i == n && wback && i != LowestSetBit(registers) then 3421 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3422 else 3423 MemA[address,4] = R[i]; 3424 address = address + 4; 3425 3426 if registers<15> == ’1’ then // Only possible for encoding A1 3427 MemA[address,4] = PCStoreValue(); 3428 3429 if wback then R[n] = R[n] - 4*BitCount(registers); 3430#endif 3431 3432 3433 bool success = false; 3434 const uint32_t opcode = OpcodeAsUnsigned (&success); 3435 if (!success) 3436 return false; 3437 3438 if (ConditionPassed ()) 3439 { 3440 uint32_t n; 3441 uint32_t registers = 0; 3442 bool wback; 3443 const uint32_t addr_byte_size = GetAddressByteSize(); 3444 3445 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3446 switch (encoding) 3447 { 3448 case eEncodingT1: 3449 // if W == ’1’ && Rn == ’1101’ then SEE PUSH; 3450 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 3451 { 3452 // See PUSH 3453 } 3454 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3455 n = Bits32 (opcode, 19, 16); 3456 registers = Bits32 (opcode, 15, 0); 3457 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3458 wback = BitIsSet (opcode, 21); 3459 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3460 if ((n == 15) || BitCount (registers) < 2) 3461 return false; 3462 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3463 if (wback && BitIsSet (registers, n)) 3464 return false; 3465 break; 3466 3467 case eEncodingA1: 3468 // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH; 3469 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 3470 { 3471 // See Push 3472 } 3473 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3474 n = Bits32 (opcode, 19, 16); 3475 registers = Bits32 (opcode, 15, 0); 3476 wback = BitIsSet (opcode, 21); 3477 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3478 if ((n == 15) || BitCount (registers) < 1) 3479 return false; 3480 break; 3481 3482 default: 3483 return false; 3484 } 3485 3486 // address = R[n] - 4*BitCount(registers); 3487 3488 int32_t offset = 0; 3489 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3490 if (!success) 3491 return false; 3492 3493 address = address - (addr_byte_size * BitCount (registers)); 3494 3495 EmulateInstruction::Context context; 3496 context.type = EmulateInstruction::eContextRegisterStore; 3497 Register base_reg; 3498 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3499 3500 // for i = 0 to 14 3501 for (int i = 0; i < 14; ++i) 3502 { 3503 uint32_t lowest_set_bit = 14; 3504 // if registers<i> == ’1’ then 3505 if (BitIsSet (registers, i)) 3506 { 3507 if (i < lowest_set_bit) 3508 lowest_set_bit = i; 3509 // if i == n && wback && i != LowestSetBit(registers) then 3510 if ((i == n) && wback && (i != lowest_set_bit)) 3511 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3512 WriteBits32UnknownToMemory (address + offset); 3513 else 3514 { 3515 // MemA[address,4] = R[i]; 3516 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3517 if (!success) 3518 return false; 3519 3520 Register data_reg; 3521 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3522 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3523 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3524 return false; 3525 } 3526 3527 // address = address + 4; 3528 offset += addr_byte_size; 3529 } 3530 } 3531 3532 // if registers<15> == ’1’ then // Only possible for encoding A1 3533 // MemA[address,4] = PCStoreValue(); 3534 if (BitIsSet (registers, 15)) 3535 { 3536 Register pc_reg; 3537 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3538 context.SetRegisterPlusOffset (pc_reg, 8); 3539 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3540 if (!success) 3541 return false; 3542 3543 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3544 return false; 3545 } 3546 3547 // if wback then R[n] = R[n] - 4*BitCount(registers); 3548 if (wback) 3549 { 3550 offset = (addr_byte_size * BitCount (registers)) * -1; 3551 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3552 context.SetImmediateSigned (offset); 3553 addr_t data = address + offset; 3554 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3555 return false; 3556 } 3557 } 3558 return true; 3559} 3560 3561// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 3562// from a base register. The consecutive memory locations start just above this address, and the address of the last 3563// of those locations can optionally be written back to the base register. 3564bool 3565EmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding) 3566{ 3567#if 0 3568 if ConditionPassed() then 3569 EncodingSpecificOperations(); 3570 address = R[n] + 4; 3571 3572 for i = 0 to 14 3573 if registers<i> == ’1’ then 3574 if i == n && wback && i != LowestSetBit(registers) then 3575 MemA[address,4] = bits(32) UNKNOWN; 3576 else 3577 MemA[address,4] = R[i]; 3578 address = address + 4; 3579 3580 if registers<15> == ’1’ then 3581 MemA[address,4] = PCStoreValue(); 3582 3583 if wback then R[n] = R[n] + 4*BitCount(registers); 3584#endif 3585 3586 bool success = false; 3587 const uint32_t opcode = OpcodeAsUnsigned (&success); 3588 if (!success) 3589 return false; 3590 3591 if (ConditionPassed()) 3592 { 3593 uint32_t n; 3594 uint32_t registers = 0; 3595 bool wback; 3596 const uint32_t addr_byte_size = GetAddressByteSize(); 3597 3598 // EncodingSpecificOperations(); 3599 switch (encoding) 3600 { 3601 case eEncodingA1: 3602 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3603 n = Bits32 (opcode, 19, 16); 3604 registers = Bits32 (opcode, 15, 0); 3605 wback = BitIsSet (opcode, 21); 3606 3607 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3608 if ((n == 15) && (BitCount (registers) < 1)) 3609 return false; 3610 break; 3611 default: 3612 return false; 3613 } 3614 // address = R[n] + 4; 3615 3616 int32_t offset = 0; 3617 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3618 if (!success) 3619 return false; 3620 3621 address = address + addr_byte_size; 3622 3623 EmulateInstruction::Context context; 3624 context.type = EmulateInstruction::eContextRegisterStore; 3625 Register base_reg; 3626 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3627 3628 uint32_t lowest_set_bit = 14; 3629 // for i = 0 to 14 3630 for (int i = 0; i < 14; ++i) 3631 { 3632 // if registers<i> == ’1’ then 3633 if (BitIsSet (registers, i)) 3634 { 3635 if (i < lowest_set_bit) 3636 lowest_set_bit = i; 3637 // if i == n && wback && i != LowestSetBit(registers) then 3638 if ((i == n) && wback && (i != lowest_set_bit)) 3639 // MemA[address,4] = bits(32) UNKNOWN; 3640 WriteBits32UnknownToMemory (address + offset); 3641 // else 3642 else 3643 { 3644 // MemA[address,4] = R[i]; 3645 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3646 if (!success) 3647 return false; 3648 3649 Register data_reg; 3650 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3651 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3652 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3653 return false; 3654 } 3655 3656 // address = address + 4; 3657 offset += addr_byte_size; 3658 } 3659 } 3660 3661 // if registers<15> == ’1’ then 3662 // MemA[address,4] = PCStoreValue(); 3663 if (BitIsSet (registers, 15)) 3664 { 3665 Register pc_reg; 3666 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3667 context.SetRegisterPlusOffset (pc_reg, 8); 3668 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3669 if (!success) 3670 return false; 3671 3672 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3673 return false; 3674 } 3675 3676 // if wback then R[n] = R[n] + 4*BitCount(registers); 3677 if (wback) 3678 { 3679 offset = addr_byte_size * BitCount (registers); 3680 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3681 context.SetImmediateSigned (offset); 3682 addr_t data = address + offset; 3683 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3684 return false; 3685 } 3686 } 3687 return true; 3688} 3689 3690// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 3691// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 3692bool 3693EmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding) 3694{ 3695#if 0 3696 if ConditionPassed() then 3697 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3698 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3699 address = if index then offset_addr else R[n]; 3700 if UnalignedSupport() || address<1:0> == ’00’ then 3701 MemU[address,4] = R[t]; 3702 else // Can only occur before ARMv7 3703 MemU[address,4] = bits(32) UNKNOWN; 3704 if wback then R[n] = offset_addr; 3705#endif 3706 3707 bool success = false; 3708 const uint32_t opcode = OpcodeAsUnsigned (&success); 3709 if (!success) 3710 return false; 3711 3712 if (ConditionPassed()) 3713 { 3714 const uint32_t addr_byte_size = GetAddressByteSize(); 3715 3716 uint32_t t; 3717 uint32_t n; 3718 uint32_t imm32; 3719 bool index; 3720 bool add; 3721 bool wback; 3722 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 3723 switch (encoding) 3724 { 3725 case eEncodingT1: 3726 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32); 3727 t = Bits32 (opcode, 2, 0); 3728 n = Bits32 (opcode, 5, 3); 3729 imm32 = Bits32 (opcode, 10, 6) << 2; 3730 3731 // index = TRUE; add = TRUE; wback = FALSE; 3732 index = true; 3733 add = false; 3734 wback = false; 3735 break; 3736 3737 case eEncodingT2: 3738 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32); 3739 t = Bits32 (opcode, 10, 8); 3740 n = 13; 3741 imm32 = Bits32 (opcode, 7, 0) << 2; 3742 3743 // index = TRUE; add = TRUE; wback = FALSE; 3744 index = true; 3745 add = true; 3746 wback = false; 3747 break; 3748 3749 case eEncodingT3: 3750 // if Rn == ’1111’ then UNDEFINED; 3751 if (Bits32 (opcode, 19, 16) == 15) 3752 return false; 3753 3754 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3755 t = Bits32 (opcode, 15, 12); 3756 n = Bits32 (opcode, 19, 16); 3757 imm32 = Bits32 (opcode, 11, 0); 3758 3759 // index = TRUE; add = TRUE; wback = FALSE; 3760 index = true; 3761 add = true; 3762 wback = false; 3763 3764 // if t == 15 then UNPREDICTABLE; 3765 if (t == 15) 3766 return false; 3767 break; 3768 3769 case eEncodingT4: 3770 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT; 3771 // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH; 3772 // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 3773 if ((Bits32 (opcode, 19, 16) == 15) 3774 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 3775 return false; 3776 3777 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3778 t = Bits32 (opcode, 15, 12); 3779 n = Bits32 (opcode, 19, 16); 3780 imm32 = Bits32 (opcode, 7, 0); 3781 3782 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 3783 index = BitIsSet (opcode, 10); 3784 add = BitIsSet (opcode, 9); 3785 wback = BitIsSet (opcode, 8); 3786 3787 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 3788 if ((t == 15) || (wback && (n == t))) 3789 return false; 3790 break; 3791 3792 default: 3793 return false; 3794 } 3795 3796 addr_t offset_addr; 3797 addr_t address; 3798 3799 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3800 uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3801 if (!success) 3802 return false; 3803 3804 if (add) 3805 offset_addr = base_address + imm32; 3806 else 3807 offset_addr = base_address - imm32; 3808 3809 // address = if index then offset_addr else R[n]; 3810 if (index) 3811 address = offset_addr; 3812 else 3813 address = base_address; 3814 3815 EmulateInstruction::Context context; 3816 context.type = eContextRegisterStore; 3817 Register base_reg; 3818 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3819 3820 // if UnalignedSupport() || address<1:0> == ’00’ then 3821 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 3822 { 3823 // MemU[address,4] = R[t]; 3824 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 3825 if (!success) 3826 return false; 3827 3828 Register data_reg; 3829 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 3830 int32_t offset = address - base_address; 3831 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3832 if (!MemUWrite (context, address, data, addr_byte_size)) 3833 return false; 3834 } 3835 else 3836 { 3837 // MemU[address,4] = bits(32) UNKNOWN; 3838 WriteBits32UnknownToMemory (address); 3839 } 3840 3841 // if wback then R[n] = offset_addr; 3842 if (wback) 3843 { 3844 context.type = eContextRegisterLoad; 3845 context.SetAddress (offset_addr); 3846 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 3847 return false; 3848 } 3849 } 3850 return true; 3851} 3852 3853// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 3854// word from a register to memory. The offset register value can optionally be shifted. 3855bool 3856EmulateInstructionARM::EmulateSTRRegister (ARMEncoding encoding) 3857{ 3858#if 0 3859 if ConditionPassed() then 3860 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3861 offset = Shift(R[m], shift_t, shift_n, APSR.C); 3862 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 3863 address = if index then offset_addr else R[n]; 3864 if t == 15 then // Only possible for encoding A1 3865 data = PCStoreValue(); 3866 else 3867 data = R[t]; 3868 if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then 3869 MemU[address,4] = data; 3870 else // Can only occur before ARMv7 3871 MemU[address,4] = bits(32) UNKNOWN; 3872 if wback then R[n] = offset_addr; 3873#endif 3874 3875 bool success = false; 3876 const uint32_t opcode = OpcodeAsUnsigned (&success); 3877 if (!success) 3878 return false; 3879 3880 if (ConditionPassed()) 3881 { 3882 const uint32_t addr_byte_size = GetAddressByteSize(); 3883 3884 uint32_t t; 3885 uint32_t n; 3886 uint32_t m; 3887 ARM_ShifterType shift_t; 3888 uint32_t shift_n; 3889 bool index; 3890 bool add; 3891 bool wback; 3892 3893 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 3894 switch (encoding) 3895 { 3896 case eEncodingT1: 3897 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 3898 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 3899 t = Bits32 (opcode, 2, 0); 3900 n = Bits32 (opcode, 5, 3); 3901 m = Bits32 (opcode, 8, 6); 3902 3903 // index = TRUE; add = TRUE; wback = FALSE; 3904 index = true; 3905 add = true; 3906 wback = false; 3907 3908 // (shift_t, shift_n) = (SRType_LSL, 0); 3909 shift_t = SRType_LSL; 3910 shift_n = 0; 3911 break; 3912 3913 case eEncodingT2: 3914 // if Rn == ’1111’ then UNDEFINED; 3915 if (Bits32 (opcode, 19, 16) == 15) 3916 return false; 3917 3918 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 3919 t = Bits32 (opcode, 15, 12); 3920 n = Bits32 (opcode, 19, 16); 3921 m = Bits32 (opcode, 3, 0); 3922 3923 // index = TRUE; add = TRUE; wback = FALSE; 3924 index = true; 3925 add = true; 3926 wback = false; 3927 3928 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 3929 shift_t = SRType_LSL; 3930 shift_n = Bits32 (opcode, 5, 4); 3931 3932 // if t == 15 || BadReg(m) then UNPREDICTABLE; 3933 if ((t == 15) || (BadReg (m))) 3934 return false; 3935 break; 3936 3937 case eEncodingA1: 3938 { 3939 // if P == ’0’ && W == ’1’ then SEE STRT; 3940 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 3941 t = Bits32 (opcode, 15, 12); 3942 n = Bits32 (opcode, 19, 16); 3943 m = Bits32 (opcode, 3, 0); 3944 3945 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 3946 index = BitIsSet (opcode, 24); 3947 add = BitIsSet (opcode, 23); 3948 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 3949 3950 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 3951 uint32_t typ = Bits32 (opcode, 6, 5); 3952 uint32_t imm5 = Bits32 (opcode, 11, 7); 3953 shift_n = DecodeImmShift(typ, imm5, shift_t); 3954 3955 // if m == 15 then UNPREDICTABLE; 3956 if (m == 15) 3957 return false; 3958 3959 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 3960 if (wback && ((n == 15) || (n == t))) 3961 return false; 3962 3963 break; 3964 } 3965 default: 3966 return false; 3967 } 3968 3969 addr_t offset_addr; 3970 addr_t address; 3971 int32_t offset = 0; 3972 3973 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3974 if (!success) 3975 return false; 3976 3977 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 3978 if (!success) 3979 return false; 3980 3981 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 3982 offset = Shift (Rm_data, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C)); 3983 3984 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 3985 if (add) 3986 offset_addr = base_address + offset; 3987 else 3988 offset_addr = base_address - offset; 3989 3990 // address = if index then offset_addr else R[n]; 3991 if (index) 3992 address = offset_addr; 3993 else 3994 address = base_address; 3995 3996 uint32_t data; 3997 // if t == 15 then // Only possible for encoding A1 3998 if (t == 15) 3999 // data = PCStoreValue(); 4000 data = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 4001 else 4002 // data = R[t]; 4003 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4004 4005 if (!success) 4006 return false; 4007 4008 EmulateInstruction::Context context; 4009 context.type = eContextRegisterStore; 4010 4011 // if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then 4012 if (UnalignedSupport () 4013 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4014 || CurrentInstrSet() == eModeARM) 4015 { 4016 // MemU[address,4] = data; 4017 4018 Register base_reg; 4019 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4020 4021 Register data_reg; 4022 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 4023 4024 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4025 if (!MemUWrite (context, address, data, addr_byte_size)) 4026 return false; 4027 4028 } 4029 else 4030 // MemU[address,4] = bits(32) UNKNOWN; 4031 WriteBits32UnknownToMemory (address); 4032 4033 // if wback then R[n] = offset_addr; 4034 if (wback) 4035 { 4036 context.type = eContextRegisterLoad; 4037 context.SetAddress (offset_addr); 4038 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4039 return false; 4040 } 4041 4042 } 4043 return true; 4044} 4045 4046bool 4047EmulateInstructionARM::EmulateSTRBThumb (ARMEncoding encoding) 4048{ 4049#if 0 4050 if ConditionPassed() then 4051 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4052 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4053 address = if index then offset_addr else R[n]; 4054 MemU[address,1] = R[t]<7:0>; 4055 if wback then R[n] = offset_addr; 4056#endif 4057 4058 4059 bool success = false; 4060 const uint32_t opcode = OpcodeAsUnsigned (&success); 4061 if (!success) 4062 return false; 4063 4064 if (ConditionPassed ()) 4065 { 4066 uint32_t t; 4067 uint32_t n; 4068 uint32_t imm32; 4069 bool index; 4070 bool add; 4071 bool wback; 4072 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4073 switch (encoding) 4074 { 4075 case eEncodingT1: 4076 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4077 t = Bits32 (opcode, 2, 0); 4078 n = Bits32 (opcode, 5, 3); 4079 imm32 = Bits32 (opcode, 10, 6); 4080 4081 // index = TRUE; add = TRUE; wback = FALSE; 4082 index = true; 4083 add = true; 4084 wback = false; 4085 break; 4086 4087 case eEncodingT2: 4088 // if Rn == ’1111’ then UNDEFINED; 4089 if (Bits32 (opcode, 19, 16) == 15) 4090 return false; 4091 4092 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4093 t = Bits32 (opcode, 15, 12); 4094 n = Bits32 (opcode, 19, 16); 4095 imm32 = Bits32 (opcode, 11, 0); 4096 4097 // index = TRUE; add = TRUE; wback = FALSE; 4098 index = true; 4099 add = true; 4100 wback = false; 4101 4102 // if BadReg(t) then UNPREDICTABLE; 4103 if (BadReg (t)) 4104 return false; 4105 break; 4106 4107 case eEncodingT3: 4108 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRBT; 4109 // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 4110 if (Bits32 (opcode, 19, 16) == 15) 4111 return false; 4112 4113 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4114 t = Bits32 (opcode, 15, 12); 4115 n = Bits32 (opcode, 19, 16); 4116 imm32 = Bits32 (opcode, 7, 0); 4117 4118 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 4119 index = BitIsSet (opcode, 10); 4120 add = BitIsSet (opcode, 9); 4121 wback = BitIsSet (opcode, 8); 4122 4123 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4124 if ((BadReg (t)) || (wback && (n == t))) 4125 return false; 4126 break; 4127 4128 default: 4129 return false; 4130 } 4131 4132 addr_t offset_addr; 4133 addr_t address; 4134 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4135 if (!success) 4136 return false; 4137 4138 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4139 if (add) 4140 offset_addr = base_address + imm32; 4141 else 4142 offset_addr = base_address - imm32; 4143 4144 // address = if index then offset_addr else R[n]; 4145 if (index) 4146 address = offset_addr; 4147 else 4148 address = base_address; 4149 4150 // MemU[address,1] = R[t]<7:0> 4151 Register base_reg; 4152 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4153 4154 Register data_reg; 4155 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 4156 4157 EmulateInstruction::Context context; 4158 context.type = eContextRegisterStore; 4159 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4160 4161 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4162 if (!success) 4163 return false; 4164 4165 data = Bits32 (data, 7, 0); 4166 4167 if (!MemUWrite (context, address, data, 1)) 4168 return false; 4169 4170 // if wback then R[n] = offset_addr; 4171 if (wback) 4172 { 4173 context.type = eContextRegisterLoad; 4174 context.SetAddress (offset_addr); 4175 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4176 return false; 4177 } 4178 4179 } 4180 4181 return true; 4182} 4183 4184EmulateInstructionARM::ARMOpcode* 4185EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 4186{ 4187 static ARMOpcode 4188 g_arm_opcodes[] = 4189 { 4190 //---------------------------------------------------------------------- 4191 // Prologue instructions 4192 //---------------------------------------------------------------------- 4193 4194 // push register(s) 4195 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 4196 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 4197 4198 // set r7 to point to a stack offset 4199 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 4200 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 4201 // copy the stack pointer to ip 4202 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 4203 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 4204 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 4205 4206 // adjust the stack pointer 4207 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 4208 4209 // push one register 4210 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 4211 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 4212 4213 // vector push consecutive extension register(s) 4214 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 4215 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 4216 4217 //---------------------------------------------------------------------- 4218 // Epilogue instructions 4219 //---------------------------------------------------------------------- 4220 4221 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 4222 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 4223 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 4224 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 4225 4226 //---------------------------------------------------------------------- 4227 // Supervisor Call (previously Software Interrupt) 4228 //---------------------------------------------------------------------- 4229 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 4230 4231 //---------------------------------------------------------------------- 4232 // Branch instructions 4233 //---------------------------------------------------------------------- 4234 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 4235 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 4236 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 4237 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 4238 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 4239 // for example, "bx lr" 4240 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 4241 4242 //---------------------------------------------------------------------- 4243 // Data-processing instructions 4244 //---------------------------------------------------------------------- 4245 // move bitwise not 4246 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNRdImm, "mvn{s} <Rd>, #<const>"}, 4247 // asr (immediate) 4248 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 4249 // asr (register) 4250 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 4251 // lsl (immediate) 4252 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 4253 // lsl (register) 4254 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 4255 // lsr (immediate) 4256 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 4257 // lsr (register) 4258 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 4259 // rrx is a special case encoding of ror (immediate) 4260 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 4261 // ror (immediate) 4262 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 4263 // ror (register) 4264 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 4265 4266 //---------------------------------------------------------------------- 4267 // Load instructions 4268 //---------------------------------------------------------------------- 4269 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 4270 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 4271 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 4272 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 4273 4274 //---------------------------------------------------------------------- 4275 // Store instructions 4276 //---------------------------------------------------------------------- 4277 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 4278 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 4279 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 4280 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 4281 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" } 4282 4283 4284 }; 4285 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 4286 4287 for (size_t i=0; i<k_num_arm_opcodes; ++i) 4288 { 4289 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 4290 return &g_arm_opcodes[i]; 4291 } 4292 return NULL; 4293} 4294 4295 4296EmulateInstructionARM::ARMOpcode* 4297EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 4298{ 4299 4300 static ARMOpcode 4301 g_thumb_opcodes[] = 4302 { 4303 //---------------------------------------------------------------------- 4304 // Prologue instructions 4305 //---------------------------------------------------------------------- 4306 4307 // push register(s) 4308 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 4309 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 4310 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 4311 4312 // set r7 to point to a stack offset 4313 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 4314 // copy the stack pointer to r7 4315 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 4316 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 4317 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 4318 4319 // PC-relative load into register (see also EmulateAddSPRm) 4320 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 4321 4322 // adjust the stack pointer 4323 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 4324 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 4325 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 4326 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 4327 4328 // vector push consecutive extension register(s) 4329 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 4330 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 4331 4332 //---------------------------------------------------------------------- 4333 // Epilogue instructions 4334 //---------------------------------------------------------------------- 4335 4336 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 4337 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 4338 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 4339 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 4340 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 4341 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 4342 4343 //---------------------------------------------------------------------- 4344 // Supervisor Call (previously Software Interrupt) 4345 //---------------------------------------------------------------------- 4346 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 4347 4348 //---------------------------------------------------------------------- 4349 // If Then makes up to four following instructions conditional. 4350 //---------------------------------------------------------------------- 4351 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 4352 4353 //---------------------------------------------------------------------- 4354 // Branch instructions 4355 //---------------------------------------------------------------------- 4356 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 4357 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 4358 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 4359 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 4360 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 4361 // J1 == J2 == 1 4362 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 4363 // J1 == J2 == 1 4364 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 4365 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 4366 // for example, "bx lr" 4367 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 4368 // compare and branch 4369 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 4370 // table branch byte 4371 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 4372 // table branch halfword 4373 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 4374 4375 //---------------------------------------------------------------------- 4376 // Data-processing instructions 4377 //---------------------------------------------------------------------- 4378 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 4379 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 4380 // Can update PC! 4381 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 4382 // move from high register to high register 4383 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 4384 // move from low register to low register 4385 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 4386 // move immediate 4387 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 4388 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 4389 // move bitwise not 4390 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNRdImm, "mvn{s} <Rd>, #<const>"}, 4391 // compare a register with immediate 4392 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPRnImm, "cmp<c> <Rn>, #imm8"}, 4393 // compare Rn with Rm (Rn and Rm both from r0-r7) 4394 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPRnRm, "cmp<c> <Rn>, <Rm>"}, 4395 // compare Rn with Rm (Rn and Rm not both from r0-r7) 4396 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPRnRm, "cmp<c> <Rn>, <Rm>"}, 4397 // asr (immediate) 4398 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 4399 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 4400 // asr (register) 4401 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 4402 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 4403 // lsl (immediate) 4404 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 4405 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 4406 // lsl (register) 4407 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 4408 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 4409 // lsr (immediate) 4410 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 4411 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 4412 // lsr (register) 4413 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 4414 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 4415 // rrx is a special case encoding of ror (immediate) 4416 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 4417 // ror (immediate) 4418 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 4419 // ror (register) 4420 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 4421 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 4422 4423 //---------------------------------------------------------------------- 4424 // Load instructions 4425 //---------------------------------------------------------------------- 4426 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 4427 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 4428 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 4429 { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 4430 // Thumb2 PC-relative load into register 4431 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 4432 4433 //---------------------------------------------------------------------- 4434 // Store instructions 4435 //---------------------------------------------------------------------- 4436 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 4437 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 4438 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 4439 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>{,#<imm>}]" }, 4440 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [SP,#<imm>]" }, 4441 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt [<Rn>,#<imm12>]" }, 4442 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>,#+/-<imm8>]" }, 4443 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> {<Rn> <Rm>]" }, 4444 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt> [<Rn> <Rm> {lsl #imm2>}]" }, 4445 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> [<Rn> #<imm5>]" }, 4446 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt> [<Rn> #<imm12>]" }, 4447 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> [<Rn>, #+/-<imm8>]{!}" } 4448 }; 4449 4450 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 4451 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 4452 { 4453 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 4454 return &g_thumb_opcodes[i]; 4455 } 4456 return NULL; 4457} 4458 4459bool 4460EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 4461{ 4462 m_arm_isa = 0; 4463 const char *arch_cstr = arch.AsCString (); 4464 if (arch_cstr) 4465 { 4466 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 4467 else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 4468 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 4469 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 4470 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 4471 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 4472 else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 4473 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 4474 else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 4475 else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 4476 } 4477 return m_arm_isa != 0; 4478} 4479 4480 4481bool 4482EmulateInstructionARM::ReadInstruction () 4483{ 4484 bool success = false; 4485 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 4486 if (success) 4487 { 4488 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 4489 if (success) 4490 { 4491 Context read_inst_context; 4492 read_inst_context.type = eContextReadOpcode; 4493 read_inst_context.SetNoArgs (); 4494 4495 if (m_inst_cpsr & MASK_CPSR_T) 4496 { 4497 m_inst_mode = eModeThumb; 4498 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 4499 4500 if (success) 4501 { 4502 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 4503 { 4504 m_inst.opcode_type = eOpcode16; 4505 m_inst.opcode.inst16 = thumb_opcode; 4506 } 4507 else 4508 { 4509 m_inst.opcode_type = eOpcode32; 4510 m_inst.opcode.inst32 = (thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success); 4511 } 4512 } 4513 } 4514 else 4515 { 4516 m_inst_mode = eModeARM; 4517 m_inst.opcode_type = eOpcode32; 4518 m_inst.opcode.inst32 = MemARead(read_inst_context, pc, 4, 0, &success); 4519 } 4520 } 4521 } 4522 if (!success) 4523 { 4524 m_inst_mode = eModeInvalid; 4525 m_inst_pc = LLDB_INVALID_ADDRESS; 4526 } 4527 return success; 4528} 4529 4530uint32_t 4531EmulateInstructionARM::ArchVersion () 4532{ 4533 return m_arm_isa; 4534} 4535 4536bool 4537EmulateInstructionARM::ConditionPassed () 4538{ 4539 if (m_inst_cpsr == 0) 4540 return false; 4541 4542 const uint32_t cond = CurrentCond (); 4543 4544 if (cond == UINT32_MAX) 4545 return false; 4546 4547 bool result = false; 4548 switch (UnsignedBits(cond, 3, 1)) 4549 { 4550 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 4551 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 4552 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 4553 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 4554 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 4555 case 5: 4556 { 4557 bool n = (m_inst_cpsr & MASK_CPSR_N); 4558 bool v = (m_inst_cpsr & MASK_CPSR_V); 4559 result = n == v; 4560 } 4561 break; 4562 case 6: 4563 { 4564 bool n = (m_inst_cpsr & MASK_CPSR_N); 4565 bool v = (m_inst_cpsr & MASK_CPSR_V); 4566 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 4567 } 4568 break; 4569 case 7: 4570 result = true; 4571 break; 4572 } 4573 4574 if (cond & 1) 4575 result = !result; 4576 return result; 4577} 4578 4579uint32_t 4580EmulateInstructionARM::CurrentCond () 4581{ 4582 switch (m_inst_mode) 4583 { 4584 default: 4585 case eModeInvalid: 4586 break; 4587 4588 case eModeARM: 4589 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 4590 4591 case eModeThumb: 4592 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 4593 // 'cond' field of the encoding. 4594 if (m_inst.opcode_type == eOpcode16 && 4595 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 4596 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 4597 { 4598 return Bits32(m_inst.opcode.inst16, 11, 7); 4599 } 4600 else if (m_inst.opcode_type == eOpcode32 && 4601 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 4602 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 4603 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 4604 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 4605 { 4606 return Bits32(m_inst.opcode.inst32, 25, 22); 4607 } 4608 4609 return m_it_session.GetCond(); 4610 } 4611 return UINT32_MAX; // Return invalid value 4612} 4613 4614bool 4615EmulateInstructionARM::InITBlock() 4616{ 4617 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 4618} 4619 4620bool 4621EmulateInstructionARM::LastInITBlock() 4622{ 4623 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 4624} 4625 4626bool 4627EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 4628{ 4629 addr_t target; 4630 4631 // Check the current instruction set. 4632 if (CurrentInstrSet() == eModeARM) 4633 target = addr & 0xfffffffc; 4634 else 4635 target = addr & 0xfffffffe; 4636 4637 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 4638 return false; 4639 4640 return true; 4641} 4642 4643// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 4644bool 4645EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 4646{ 4647 addr_t target; 4648 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 4649 // we want to record it and issue a WriteRegister callback so the clients 4650 // can track the mode changes accordingly. 4651 bool cpsr_changed = false; 4652 4653 if (BitIsSet(addr, 0)) 4654 { 4655 if (CurrentInstrSet() != eModeThumb) 4656 { 4657 SelectInstrSet(eModeThumb); 4658 cpsr_changed = true; 4659 } 4660 target = addr & 0xfffffffe; 4661 context.SetMode (eModeThumb); 4662 } 4663 else if (BitIsClear(addr, 1)) 4664 { 4665 if (CurrentInstrSet() != eModeARM) 4666 { 4667 SelectInstrSet(eModeARM); 4668 cpsr_changed = true; 4669 } 4670 target = addr & 0xfffffffc; 4671 context.SetMode (eModeARM); 4672 } 4673 else 4674 return false; // address<1:0> == '10' => UNPREDICTABLE 4675 4676 if (cpsr_changed) 4677 { 4678 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 4679 return false; 4680 } 4681 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 4682 return false; 4683 4684 return true; 4685} 4686 4687// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 4688bool 4689EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 4690{ 4691 if (ArchVersion() >= ARMv5T) 4692 return BXWritePC(context, addr); 4693 else 4694 return BranchWritePC((const Context)context, addr); 4695} 4696 4697// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 4698bool 4699EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 4700{ 4701 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 4702 return BXWritePC(context, addr); 4703 else 4704 return BranchWritePC((const Context)context, addr); 4705} 4706 4707EmulateInstructionARM::Mode 4708EmulateInstructionARM::CurrentInstrSet () 4709{ 4710 return m_inst_mode; 4711} 4712 4713// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 4714// ReadInstruction() is performed. This function has a side effect of updating 4715// the m_new_inst_cpsr member variable if necessary. 4716bool 4717EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 4718{ 4719 m_new_inst_cpsr = m_inst_cpsr; 4720 switch (arm_or_thumb) 4721 { 4722 default: 4723 return false; 4724 eModeARM: 4725 // Clear the T bit. 4726 m_new_inst_cpsr &= ~MASK_CPSR_T; 4727 break; 4728 eModeThumb: 4729 // Set the T bit. 4730 m_new_inst_cpsr |= MASK_CPSR_T; 4731 break; 4732 } 4733 return true; 4734} 4735 4736// This function returns TRUE if the processor currently provides support for 4737// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 4738// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 4739bool 4740EmulateInstructionARM::UnalignedSupport() 4741{ 4742 return (ArchVersion() >= ARMv7); 4743} 4744 4745// The main addition and subtraction instructions can produce status information 4746// about both unsigned carry and signed overflow conditions. This status 4747// information can be used to synthesize multi-word additions and subtractions. 4748EmulateInstructionARM::AddWithCarryResult 4749EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 4750{ 4751 uint32_t result; 4752 uint8_t carry_out; 4753 uint8_t overflow; 4754 4755 uint64_t unsigned_sum = x + y + carry_in; 4756 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 4757 4758 result = UnsignedBits(unsigned_sum, 31, 0); 4759 carry_out = (result == unsigned_sum ? 0 : 1); 4760 overflow = ((int32_t)result == signed_sum ? 0 : 1); 4761 4762 AddWithCarryResult res = { result, carry_out, overflow }; 4763 return res; 4764} 4765 4766// Write the result to the ARM core register Rd, and optionally update the 4767// condition flags based on the result. 4768// 4769// This helper method tries to encapsulate the following pseudocode from the 4770// ARM Architecture Reference Manual: 4771// 4772// if d == 15 then // Can only occur for encoding A1 4773// ALUWritePC(result); // setflags is always FALSE here 4774// else 4775// R[d] = result; 4776// if setflags then 4777// APSR.N = result<31>; 4778// APSR.Z = IsZeroBit(result); 4779// APSR.C = carry; 4780// // APSR.V unchanged 4781// 4782// In the above case, the API client does not pass in the overflow arg, which 4783// defaults to ~0u. 4784bool 4785EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 4786 const uint32_t result, 4787 const uint32_t Rd, 4788 bool setflags, 4789 const uint32_t carry, 4790 const uint32_t overflow) 4791{ 4792 if (Rd == 15) 4793 { 4794 if (!ALUWritePC (context, result)) 4795 return false; 4796 } 4797 else 4798 { 4799 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 4800 return false; 4801 if (setflags) 4802 return WriteFlags (context, result, carry, overflow); 4803 } 4804 return true; 4805} 4806 4807// This helper method tries to encapsulate the following pseudocode from the 4808// ARM Architecture Reference Manual: 4809// 4810// APSR.N = result<31>; 4811// APSR.Z = IsZeroBit(result); 4812// APSR.C = carry; 4813// APSR.V = overflow 4814// 4815// Default arguments can be specified for carry and overflow parameters, which means 4816// not to update the respective flags. 4817bool 4818EmulateInstructionARM::WriteFlags (Context &context, 4819 const uint32_t result, 4820 const uint32_t carry, 4821 const uint32_t overflow) 4822{ 4823 m_new_inst_cpsr = m_inst_cpsr; 4824 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 4825 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 4826 if (carry != ~0u) 4827 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 4828 if (overflow != ~0u) 4829 SetBit32(m_new_inst_cpsr, CPSR_V, overflow); 4830 if (m_new_inst_cpsr != m_inst_cpsr) 4831 { 4832 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 4833 return false; 4834 } 4835 return true; 4836} 4837 4838bool 4839EmulateInstructionARM::EvaluateInstruction () 4840{ 4841 // Advance the ITSTATE bits to their values for the next instruction. 4842 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 4843 m_it_session.ITAdvance(); 4844 4845 return false; 4846} 4847