EmulateInstructionARM.cpp revision d4dc4444e124b290cbe30cdaade7e97161fa47c8
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 "EmulateInstructionARM.h" 11#include "lldb/Core/ConstString.h" 12 13#include "Plugins/Process/Utility/ARMDefines.h" 14#include "Plugins/Process/Utility/ARMUtils.h" 15#include "Utility/ARM_DWARF_Registers.h" 16 17#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 18 // and CountTrailingZeros_32 function 19 20using namespace lldb; 21using namespace lldb_private; 22 23static inline uint32_t Align(uint32_t val, uint32_t alignment) 24{ 25 return alignment * (val / alignment); 26} 27 28//---------------------------------------------------------------------- 29// 30// ITSession implementation 31// 32//---------------------------------------------------------------------- 33 34// A8.6.50 35// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 36static unsigned short CountITSize(unsigned ITMask) { 37 // First count the trailing zeros of the IT mask. 38 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 39 if (TZ > 3) 40 { 41 printf("Encoding error: IT Mask '0000'\n"); 42 return 0; 43 } 44 return (4 - TZ); 45} 46 47// Init ITState. Note that at least one bit is always 1 in mask. 48bool ITSession::InitIT(unsigned short bits7_0) 49{ 50 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 51 if (ITCounter == 0) 52 return false; 53 54 // A8.6.50 IT 55 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 56 if (FirstCond == 0xF) 57 { 58 printf("Encoding error: IT FirstCond '1111'\n"); 59 return false; 60 } 61 if (FirstCond == 0xE && ITCounter != 1) 62 { 63 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 64 return false; 65 } 66 67 ITState = bits7_0; 68 return true; 69} 70 71// Update ITState if necessary. 72void ITSession::ITAdvance() 73{ 74 assert(ITCounter); 75 --ITCounter; 76 if (ITCounter == 0) 77 ITState = 0; 78 else 79 { 80 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 81 SetBits32(ITState, 4, 0, NewITState4_0); 82 } 83} 84 85// Return true if we're inside an IT Block. 86bool ITSession::InITBlock() 87{ 88 return ITCounter != 0; 89} 90 91// Return true if we're the last instruction inside an IT Block. 92bool ITSession::LastInITBlock() 93{ 94 return ITCounter == 1; 95} 96 97// Get condition bits for the current thumb instruction. 98uint32_t ITSession::GetCond() 99{ 100 if (InITBlock()) 101 return Bits32(ITState, 7, 4); 102 else 103 return COND_AL; 104} 105 106// ARM constants used during decoding 107#define REG_RD 0 108#define LDM_REGLIST 1 109#define PC_REG 15 110#define PC_REGLIST_BIT 0x8000 111 112#define ARMv4 (1u << 0) 113#define ARMv4T (1u << 1) 114#define ARMv5T (1u << 2) 115#define ARMv5TE (1u << 3) 116#define ARMv5TEJ (1u << 4) 117#define ARMv6 (1u << 5) 118#define ARMv6K (1u << 6) 119#define ARMv6T2 (1u << 7) 120#define ARMv7 (1u << 8) 121#define ARMv8 (1u << 9) 122#define ARMvAll (0xffffffffu) 123 124#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 125#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 126#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 127 128//---------------------------------------------------------------------- 129// 130// EmulateInstructionARM implementation 131// 132//---------------------------------------------------------------------- 133 134void 135EmulateInstructionARM::Initialize () 136{ 137} 138 139void 140EmulateInstructionARM::Terminate () 141{ 142} 143 144// Push Multiple Registers stores multiple registers to the stack, storing to 145// consecutive memory locations ending just below the address in SP, and updates 146// SP to point to the start of the stored data. 147bool 148EmulateInstructionARM::EmulatePush (ARMEncoding encoding) 149{ 150#if 0 151 // ARM pseudo code... 152 if (ConditionPassed()) 153 { 154 EncodingSpecificOperations(); 155 NullCheckIfThumbEE(13); 156 address = SP - 4*BitCount(registers); 157 158 for (i = 0 to 14) 159 { 160 if (registers<i> == ’1’) 161 { 162 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 163 MemA[address,4] = bits(32) UNKNOWN; 164 else 165 MemA[address,4] = R[i]; 166 address = address + 4; 167 } 168 } 169 170 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 171 MemA[address,4] = PCStoreValue(); 172 173 SP = SP - 4*BitCount(registers); 174 } 175#endif 176 177 bool success = false; 178 const uint32_t opcode = OpcodeAsUnsigned (&success); 179 if (!success) 180 return false; 181 182 if (ConditionPassed()) 183 { 184 const uint32_t addr_byte_size = GetAddressByteSize(); 185 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 186 if (!success) 187 return false; 188 uint32_t registers = 0; 189 uint32_t Rt; // the source register 190 switch (encoding) { 191 case eEncodingT1: 192 registers = Bits32(opcode, 7, 0); 193 // The M bit represents LR. 194 if (Bit32(opcode, 8)) 195 registers |= (1u << 14); 196 // if BitCount(registers) < 1 then UNPREDICTABLE; 197 if (BitCount(registers) < 1) 198 return false; 199 break; 200 case eEncodingT2: 201 // Ignore bits 15 & 13. 202 registers = Bits32(opcode, 15, 0) & ~0xa000; 203 // if BitCount(registers) < 2 then UNPREDICTABLE; 204 if (BitCount(registers) < 2) 205 return false; 206 break; 207 case eEncodingT3: 208 Rt = Bits32(opcode, 15, 12); 209 // if BadReg(t) then UNPREDICTABLE; 210 if (BadReg(Rt)) 211 return false; 212 registers = (1u << Rt); 213 break; 214 case eEncodingA1: 215 registers = Bits32(opcode, 15, 0); 216 // Instead of return false, let's handle the following case as well, 217 // which amounts to pushing one reg onto the full descending stacks. 218 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 219 break; 220 case eEncodingA2: 221 Rt = Bits32(opcode, 15, 12); 222 // if t == 13 then UNPREDICTABLE; 223 if (Rt == dwarf_sp) 224 return false; 225 registers = (1u << Rt); 226 break; 227 default: 228 return false; 229 } 230 addr_t sp_offset = addr_byte_size * BitCount (registers); 231 addr_t addr = sp - sp_offset; 232 uint32_t i; 233 234 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 235 for (i=0; i<15; ++i) 236 { 237 if (BitIsSet (registers, i)) 238 { 239 context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number 240 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 241 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 242 if (!success) 243 return false; 244 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 245 return false; 246 addr += addr_byte_size; 247 } 248 } 249 250 if (BitIsSet (registers, 15)) 251 { 252 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 253 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 254 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 255 if (!success) 256 return false; 257 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 258 return false; 259 } 260 261 context.type = EmulateInstruction::eContextAdjustStackPointer; 262 context.arg0 = eRegisterKindGeneric; 263 context.arg1 = LLDB_REGNUM_GENERIC_SP; 264 context.arg2 = -sp_offset; 265 266 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 267 return false; 268 } 269 return true; 270} 271 272// Pop Multiple Registers loads multiple registers from the stack, loading from 273// consecutive memory locations staring at the address in SP, and updates 274// SP to point just above the loaded data. 275bool 276EmulateInstructionARM::EmulatePop (ARMEncoding encoding) 277{ 278#if 0 279 // ARM pseudo code... 280 if (ConditionPassed()) 281 { 282 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 283 address = SP; 284 for i = 0 to 14 285 if registers<i> == ‘1’ then 286 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 287 if registers<15> == ‘1’ then 288 if UnalignedAllowed then 289 LoadWritePC(MemU[address,4]); 290 else 291 LoadWritePC(MemA[address,4]); 292 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 293 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 294 } 295#endif 296 297 bool success = false; 298 const uint32_t opcode = OpcodeAsUnsigned (&success); 299 if (!success) 300 return false; 301 302 if (ConditionPassed()) 303 { 304 const uint32_t addr_byte_size = GetAddressByteSize(); 305 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 306 if (!success) 307 return false; 308 uint32_t registers = 0; 309 uint32_t Rt; // the destination register 310 switch (encoding) { 311 case eEncodingT1: 312 registers = Bits32(opcode, 7, 0); 313 // The P bit represents PC. 314 if (Bit32(opcode, 8)) 315 registers |= (1u << 15); 316 // if BitCount(registers) < 1 then UNPREDICTABLE; 317 if (BitCount(registers) < 1) 318 return false; 319 break; 320 case eEncodingT2: 321 // Ignore bit 13. 322 registers = Bits32(opcode, 15, 0) & ~0x2000; 323 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 324 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 325 return false; 326 break; 327 case eEncodingT3: 328 Rt = Bits32(opcode, 15, 12); 329 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 330 if (Rt == dwarf_sp) 331 return false; 332 registers = (1u << Rt); 333 break; 334 case eEncodingA1: 335 registers = Bits32(opcode, 15, 0); 336 // Instead of return false, let's handle the following case as well, 337 // which amounts to popping one reg from the full descending stacks. 338 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 339 340 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 341 if (Bit32(opcode, 13) && ArchVersion() >= ARMv7) 342 return false; 343 break; 344 case eEncodingA2: 345 Rt = Bits32(opcode, 15, 12); 346 // if t == 13 then UNPREDICTABLE; 347 if (Rt == dwarf_sp) 348 return false; 349 registers = (1u << Rt); 350 break; 351 default: 352 return false; 353 } 354 addr_t sp_offset = addr_byte_size * BitCount (registers); 355 addr_t addr = sp; 356 uint32_t i, data; 357 358 EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 }; 359 for (i=0; i<15; ++i) 360 { 361 if (BitIsSet (registers, i)) 362 { 363 context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number 364 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 365 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 366 if (!success) 367 return false; 368 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data)) 369 return false; 370 addr += addr_byte_size; 371 } 372 } 373 374 if (BitIsSet (registers, 15)) 375 { 376 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 377 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 378 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 379 if (!success) 380 return false; 381 // In ARMv5T and above, this is an interworking branch. 382 if (!LoadWritePC(context, data)) 383 return false; 384 addr += addr_byte_size; 385 } 386 387 context.type = EmulateInstruction::eContextAdjustStackPointer; 388 context.arg0 = eRegisterKindGeneric; 389 context.arg1 = LLDB_REGNUM_GENERIC_SP; 390 context.arg2 = sp_offset; 391 392 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 393 return false; 394 } 395 return true; 396} 397 398// Set r7 or ip to point to saved value residing within the stack. 399// ADD (SP plus immediate) 400bool 401EmulateInstructionARM::EmulateAddRdSPImmediate (ARMEncoding encoding) 402{ 403#if 0 404 // ARM pseudo code... 405 if (ConditionPassed()) 406 { 407 EncodingSpecificOperations(); 408 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 409 if d == 15 then 410 ALUWritePC(result); // setflags is always FALSE here 411 else 412 R[d] = result; 413 if setflags then 414 APSR.N = result<31>; 415 APSR.Z = IsZeroBit(result); 416 APSR.C = carry; 417 APSR.V = overflow; 418 } 419#endif 420 421 bool success = false; 422 const uint32_t opcode = OpcodeAsUnsigned (&success); 423 if (!success) 424 return false; 425 426 if (ConditionPassed()) 427 { 428 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 429 if (!success) 430 return false; 431 uint32_t Rd; // the destination register 432 uint32_t imm32; 433 switch (encoding) { 434 case eEncodingT1: 435 Rd = 7; 436 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 437 break; 438 case eEncodingA1: 439 Rd = Bits32(opcode, 15, 12); 440 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 441 break; 442 default: 443 return false; 444 } 445 addr_t sp_offset = imm32; 446 addr_t addr = sp + sp_offset; // a pointer to the stack area 447 448 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 449 eRegisterKindGeneric, 450 LLDB_REGNUM_GENERIC_SP, 451 sp_offset }; 452 453 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 454 return false; 455 } 456 return true; 457} 458 459// Set r7 or ip to the current stack pointer. 460// MOV (register) 461bool 462EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding) 463{ 464#if 0 465 // ARM pseudo code... 466 if (ConditionPassed()) 467 { 468 EncodingSpecificOperations(); 469 result = R[m]; 470 if d == 15 then 471 ALUWritePC(result); // setflags is always FALSE here 472 else 473 R[d] = result; 474 if setflags then 475 APSR.N = result<31>; 476 APSR.Z = IsZeroBit(result); 477 // APSR.C unchanged 478 // APSR.V unchanged 479 } 480#endif 481 482 bool success = false; 483 //const uint32_t opcode = OpcodeAsUnsigned (&success); 484 //if (!success) 485 // return false; 486 487 if (ConditionPassed()) 488 { 489 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 490 if (!success) 491 return false; 492 uint32_t Rd; // the destination register 493 switch (encoding) { 494 case eEncodingT1: 495 Rd = 7; 496 break; 497 case eEncodingA1: 498 Rd = 12; 499 break; 500 default: 501 return false; 502 } 503 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 504 eRegisterKindGeneric, 505 LLDB_REGNUM_GENERIC_SP, 506 0 }; 507 508 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 509 return false; 510 } 511 return true; 512} 513 514// Move from high register (r8-r15) to low register (r0-r7). 515// MOV (register) 516bool 517EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding) 518{ 519 return EmulateMovRdRm (encoding); 520} 521 522// Move from register to register. 523// MOV (register) 524bool 525EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding) 526{ 527#if 0 528 // ARM pseudo code... 529 if (ConditionPassed()) 530 { 531 EncodingSpecificOperations(); 532 result = R[m]; 533 if d == 15 then 534 ALUWritePC(result); // setflags is always FALSE here 535 else 536 R[d] = result; 537 if setflags then 538 APSR.N = result<31>; 539 APSR.Z = IsZeroBit(result); 540 // APSR.C unchanged 541 // APSR.V unchanged 542 } 543#endif 544 545 bool success = false; 546 const uint32_t opcode = OpcodeAsUnsigned (&success); 547 if (!success) 548 return false; 549 550 if (ConditionPassed()) 551 { 552 uint32_t Rm; // the source register 553 uint32_t Rd; // the destination register 554 bool setflags; 555 switch (encoding) { 556 case eEncodingT1: 557 Rm = Bits32(opcode, 6, 3); 558 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1); 559 setflags = false; 560 break; 561 case eEncodingT2: 562 Rm = Bits32(opcode, 5, 3); 563 Rd = Bits32(opcode, 2, 1); 564 setflags = true; 565 break; 566 default: 567 return false; 568 } 569 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 570 if (!success) 571 return false; 572 573 // The context specifies that Rm is to be moved into Rd. 574 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 575 eRegisterKindDWARF, 576 dwarf_r0 + Rm, 577 0 }; 578 579 if (Rd == 15) 580 { 581 if (!ALUWritePC (context, reg_value)) 582 return false; 583 } 584 else 585 { 586 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value)) 587 return false; 588 if (setflags) 589 { 590 m_new_inst_cpsr = m_inst_cpsr; 591 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(reg_value, CPSR_N)); 592 SetBit32(m_new_inst_cpsr, CPSR_Z, reg_value == 0 ? 1 : 0); 593 if (m_new_inst_cpsr != m_inst_cpsr) 594 { 595 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 596 return false; 597 } 598 } 599 } 600 } 601 return true; 602} 603 604// PC relative immediate load into register, possibly followed by ADD (SP plus register). 605// LDR (literal) 606bool 607EmulateInstructionARM::EmulateLDRRdPCRelative (ARMEncoding encoding) 608{ 609#if 0 610 // ARM pseudo code... 611 if (ConditionPassed()) 612 { 613 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 614 base = Align(PC,4); 615 address = if add then (base + imm32) else (base - imm32); 616 data = MemU[address,4]; 617 if t == 15 then 618 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 619 elsif UnalignedSupport() || address<1:0> = ‘00’ then 620 R[t] = data; 621 else // Can only apply before ARMv7 622 if CurrentInstrSet() == InstrSet_ARM then 623 R[t] = ROR(data, 8*UInt(address<1:0>)); 624 else 625 R[t] = bits(32) UNKNOWN; 626 } 627#endif 628 629 bool success = false; 630 const uint32_t opcode = OpcodeAsUnsigned (&success); 631 if (!success) 632 return false; 633 634 if (ConditionPassed()) 635 { 636 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 637 if (!success) 638 return false; 639 640 // PC relative immediate load context 641 EmulateInstruction::Context context = {EmulateInstruction::eContextRegisterPlusOffset, 642 eRegisterKindGeneric, 643 LLDB_REGNUM_GENERIC_PC, 644 0}; 645 uint32_t Rd; // the destination register 646 uint32_t imm32; // immediate offset from the PC 647 addr_t addr; // the PC relative address 648 uint32_t data; // the literal data value from the PC relative load 649 switch (encoding) { 650 case eEncodingT1: 651 Rd = Bits32(opcode, 10, 8); 652 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 653 addr = pc + 4 + imm32; 654 context.arg2 = 4 + imm32; 655 break; 656 default: 657 return false; 658 } 659 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 660 if (!success) 661 return false; 662 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, data)) 663 return false; 664 } 665 return true; 666} 667 668// An add operation to adjust the SP. 669// ADD (SP plus immediate) 670bool 671EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding) 672{ 673#if 0 674 // ARM pseudo code... 675 if (ConditionPassed()) 676 { 677 EncodingSpecificOperations(); 678 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 679 if d == 15 then // Can only occur for ARM encoding 680 ALUWritePC(result); // setflags is always FALSE here 681 else 682 R[d] = result; 683 if setflags then 684 APSR.N = result<31>; 685 APSR.Z = IsZeroBit(result); 686 APSR.C = carry; 687 APSR.V = overflow; 688 } 689#endif 690 691 bool success = false; 692 const uint32_t opcode = OpcodeAsUnsigned (&success); 693 if (!success) 694 return false; 695 696 if (ConditionPassed()) 697 { 698 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 699 if (!success) 700 return false; 701 uint32_t imm32; // the immediate operand 702 switch (encoding) { 703 case eEncodingT2: 704 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 705 break; 706 default: 707 return false; 708 } 709 addr_t sp_offset = imm32; 710 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 711 712 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 713 eRegisterKindGeneric, 714 LLDB_REGNUM_GENERIC_SP, 715 sp_offset }; 716 717 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 718 return false; 719 } 720 return true; 721} 722 723// An add operation to adjust the SP. 724// ADD (SP plus register) 725bool 726EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding) 727{ 728#if 0 729 // ARM pseudo code... 730 if (ConditionPassed()) 731 { 732 EncodingSpecificOperations(); 733 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 734 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 735 if d == 15 then 736 ALUWritePC(result); // setflags is always FALSE here 737 else 738 R[d] = result; 739 if setflags then 740 APSR.N = result<31>; 741 APSR.Z = IsZeroBit(result); 742 APSR.C = carry; 743 APSR.V = overflow; 744 } 745#endif 746 747 bool success = false; 748 const uint32_t opcode = OpcodeAsUnsigned (&success); 749 if (!success) 750 return false; 751 752 if (ConditionPassed()) 753 { 754 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 755 if (!success) 756 return false; 757 uint32_t Rm; // the second operand 758 switch (encoding) { 759 case eEncodingT2: 760 Rm = Bits32(opcode, 6, 3); 761 break; 762 default: 763 return false; 764 } 765 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 766 if (!success) 767 return false; 768 769 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 770 771 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 772 eRegisterKindGeneric, 773 LLDB_REGNUM_GENERIC_SP, 774 reg_value }; 775 776 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 777 return false; 778 } 779 return true; 780} 781 782// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 783// at a PC-relative address, and changes instruction set from ARM to Thumb, or 784// from Thumb to ARM. 785// BLX (immediate) 786bool 787EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 788{ 789#if 0 790 // ARM pseudo code... 791 if (ConditionPassed()) 792 { 793 EncodingSpecificOperations(); 794 if CurrentInstrSet() == InstrSet_ARM then 795 LR = PC - 4; 796 else 797 LR = PC<31:1> : '1'; 798 if targetInstrSet == InstrSet_ARM then 799 targetAddress = Align(PC,4) + imm32; 800 else 801 targetAddress = PC + imm32; 802 SelectInstrSet(targetInstrSet); 803 BranchWritePC(targetAddress); 804 } 805#endif 806 807 bool success = false; 808 const uint32_t opcode = OpcodeAsUnsigned (&success); 809 if (!success) 810 return false; 811 812 if (ConditionPassed()) 813 { 814 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 815 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 816 if (!success) 817 return false; 818 addr_t lr; // next instruction address 819 addr_t target; // target address 820 int32_t imm32; // PC-relative offset 821 switch (encoding) { 822 case eEncodingT1: 823 { 824 lr = (pc + 4) | 1u; // return address 825 uint32_t S = Bit32(opcode, 26); 826 uint32_t imm10 = Bits32(opcode, 25, 16); 827 uint32_t J1 = Bit32(opcode, 13); 828 uint32_t J2 = Bit32(opcode, 11); 829 uint32_t imm11 = Bits32(opcode, 10, 0); 830 uint32_t I1 = !(J1 ^ S); 831 uint32_t I2 = !(J2 ^ S); 832 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 833 imm32 = llvm::SignExtend32<25>(imm25); 834 target = pc + 4 + imm32; 835 context.arg1 = 4 + imm32; // signed offset 836 context.arg2 = eModeThumb; // target instruction set 837 break; 838 } 839 case eEncodingT2: 840 { 841 lr = (pc + 4) | 1u; // return address 842 uint32_t S = Bit32(opcode, 26); 843 uint32_t imm10H = Bits32(opcode, 25, 16); 844 uint32_t J1 = Bit32(opcode, 13); 845 uint32_t J2 = Bit32(opcode, 11); 846 uint32_t imm10L = Bits32(opcode, 10, 1); 847 uint32_t I1 = !(J1 ^ S); 848 uint32_t I2 = !(J2 ^ S); 849 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 850 imm32 = llvm::SignExtend32<25>(imm25); 851 target = Align(pc + 4, 4) + imm32; 852 context.arg1 = 4 + imm32; // signed offset 853 context.arg2 = eModeARM; // target instruction set 854 break; 855 } 856 case eEncodingA1: 857 lr = pc + 4; // return address 858 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 859 target = Align(pc + 8, 4) + imm32; 860 context.arg1 = 8 + imm32; // signed offset 861 context.arg2 = eModeARM; // target instruction set 862 break; 863 case eEncodingA2: 864 lr = pc + 4; // return address 865 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 866 target = pc + 8 + imm32; 867 context.arg1 = 8 + imm32; // signed offset 868 context.arg2 = eModeThumb; // target instruction set 869 break; 870 default: 871 return false; 872 } 873 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 874 return false; 875 if (!BranchWritePC(context, target)) 876 return false; 877 } 878 return true; 879} 880 881// Branch with Link and Exchange (register) calls a subroutine at an address and 882// instruction set specified by a register. 883// BLX (register) 884bool 885EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 886{ 887#if 0 888 // ARM pseudo code... 889 if (ConditionPassed()) 890 { 891 EncodingSpecificOperations(); 892 target = R[m]; 893 if CurrentInstrSet() == InstrSet_ARM then 894 next_instr_addr = PC - 4; 895 LR = next_instr_addr; 896 else 897 next_instr_addr = PC - 2; 898 LR = next_instr_addr<31:1> : ‘1’; 899 BXWritePC(target); 900 } 901#endif 902 903 bool success = false; 904 const uint32_t opcode = OpcodeAsUnsigned (&success); 905 if (!success) 906 return false; 907 908 if (ConditionPassed()) 909 { 910 EmulateInstruction::Context context = { EmulateInstruction::eContextAbsoluteBranchRegister, 0, 0, 0}; 911 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 912 addr_t lr; // next instruction address 913 addr_t target; // target address 914 if (!success) 915 return false; 916 uint32_t Rm; // the register with the target address 917 switch (encoding) { 918 case eEncodingT1: 919 lr = (pc + 2) | 1u; // return address 920 Rm = Bits32(opcode, 6, 3); 921 // if m == 15 then UNPREDICTABLE; 922 if (Rm == 15) 923 return false; 924 target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 925 break; 926 case eEncodingA1: 927 lr = pc + 4; // return address 928 Rm = Bits32(opcode, 3, 0); 929 // if m == 15 then UNPREDICTABLE; 930 if (Rm == 15) 931 return false; 932 target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 933 break; 934 default: 935 return false; 936 } 937 context.arg0 = eRegisterKindDWARF; 938 context.arg1 = dwarf_r0 + Rm; 939 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 940 return false; 941 if (!BXWritePC(context, target)) 942 return false; 943 } 944 return true; 945} 946 947// Set r7 to point to some ip offset. 948// SUB (immediate) 949bool 950EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding) 951{ 952#if 0 953 // ARM pseudo code... 954 if (ConditionPassed()) 955 { 956 EncodingSpecificOperations(); 957 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 958 if d == 15 then // Can only occur for ARM encoding 959 ALUWritePC(result); // setflags is always FALSE here 960 else 961 R[d] = result; 962 if setflags then 963 APSR.N = result<31>; 964 APSR.Z = IsZeroBit(result); 965 APSR.C = carry; 966 APSR.V = overflow; 967 } 968#endif 969 970 bool success = false; 971 const uint32_t opcode = OpcodeAsUnsigned (&success); 972 if (!success) 973 return false; 974 975 if (ConditionPassed()) 976 { 977 const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success); 978 if (!success) 979 return false; 980 uint32_t imm32; 981 switch (encoding) { 982 case eEncodingA1: 983 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 984 break; 985 default: 986 return false; 987 } 988 addr_t ip_offset = imm32; 989 addr_t addr = ip - ip_offset; // the adjusted ip value 990 991 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 992 eRegisterKindDWARF, 993 dwarf_r12, 994 -ip_offset }; 995 996 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 997 return false; 998 } 999 return true; 1000} 1001 1002// Set ip to point to some stack offset. 1003// SUB (SP minus immediate) 1004bool 1005EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding) 1006{ 1007#if 0 1008 // ARM pseudo code... 1009 if (ConditionPassed()) 1010 { 1011 EncodingSpecificOperations(); 1012 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1013 if d == 15 then // Can only occur for ARM encoding 1014 ALUWritePC(result); // setflags is always FALSE here 1015 else 1016 R[d] = result; 1017 if setflags then 1018 APSR.N = result<31>; 1019 APSR.Z = IsZeroBit(result); 1020 APSR.C = carry; 1021 APSR.V = overflow; 1022 } 1023#endif 1024 1025 bool success = false; 1026 const uint32_t opcode = OpcodeAsUnsigned (&success); 1027 if (!success) 1028 return false; 1029 1030 if (ConditionPassed()) 1031 { 1032 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1033 if (!success) 1034 return false; 1035 uint32_t imm32; 1036 switch (encoding) { 1037 case eEncodingA1: 1038 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1039 break; 1040 default: 1041 return false; 1042 } 1043 addr_t sp_offset = imm32; 1044 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1045 1046 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1047 eRegisterKindGeneric, 1048 LLDB_REGNUM_GENERIC_SP, 1049 -sp_offset }; 1050 1051 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1052 return false; 1053 } 1054 return true; 1055} 1056 1057// A sub operation to adjust the SP -- allocate space for local storage. 1058bool 1059EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding) 1060{ 1061#if 0 1062 // ARM pseudo code... 1063 if (ConditionPassed()) 1064 { 1065 EncodingSpecificOperations(); 1066 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1067 if d == 15 then // Can only occur for ARM encoding 1068 ALUWritePC(result); // setflags is always FALSE here 1069 else 1070 R[d] = result; 1071 if setflags then 1072 APSR.N = result<31>; 1073 APSR.Z = IsZeroBit(result); 1074 APSR.C = carry; 1075 APSR.V = overflow; 1076 } 1077#endif 1078 1079 bool success = false; 1080 const uint32_t opcode = OpcodeAsUnsigned (&success); 1081 if (!success) 1082 return false; 1083 1084 if (ConditionPassed()) 1085 { 1086 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1087 if (!success) 1088 return false; 1089 uint32_t imm32; 1090 switch (encoding) { 1091 case eEncodingT1: 1092 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1093 case eEncodingT2: 1094 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1095 break; 1096 case eEncodingT3: 1097 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1098 break; 1099 case eEncodingA1: 1100 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1101 break; 1102 default: 1103 return false; 1104 } 1105 addr_t sp_offset = imm32; 1106 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1107 1108 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 1109 eRegisterKindGeneric, 1110 LLDB_REGNUM_GENERIC_SP, 1111 -sp_offset }; 1112 1113 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1114 return false; 1115 } 1116 return true; 1117} 1118 1119// A store operation to the stack that also updates the SP. 1120bool 1121EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1122{ 1123#if 0 1124 // ARM pseudo code... 1125 if (ConditionPassed()) 1126 { 1127 EncodingSpecificOperations(); 1128 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1129 address = if index then offset_addr else R[n]; 1130 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1131 if wback then R[n] = offset_addr; 1132 } 1133#endif 1134 1135 bool success = false; 1136 const uint32_t opcode = OpcodeAsUnsigned (&success); 1137 if (!success) 1138 return false; 1139 1140 if (ConditionPassed()) 1141 { 1142 const uint32_t addr_byte_size = GetAddressByteSize(); 1143 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1144 if (!success) 1145 return false; 1146 uint32_t Rt; // the source register 1147 uint32_t imm12; 1148 switch (encoding) { 1149 case eEncodingA1: 1150 Rt = Bits32(opcode, 15, 12); 1151 imm12 = Bits32(opcode, 11, 0); 1152 break; 1153 default: 1154 return false; 1155 } 1156 addr_t sp_offset = imm12; 1157 addr_t addr = sp - sp_offset; 1158 1159 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 1160 if (Rt != 15) 1161 { 1162 context.arg1 = dwarf_r0 + Rt; // arg1 in the context is the DWARF register number 1163 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1164 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 1165 if (!success) 1166 return false; 1167 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 1168 return false; 1169 } 1170 else 1171 { 1172 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 1173 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1174 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1175 if (!success) 1176 return false; 1177 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 1178 return false; 1179 } 1180 1181 context.type = EmulateInstruction::eContextAdjustStackPointer; 1182 context.arg0 = eRegisterKindGeneric; 1183 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1184 context.arg2 = -sp_offset; 1185 1186 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1187 return false; 1188 } 1189 return true; 1190} 1191 1192// Vector Push stores multiple extension registers to the stack. 1193// It also updates SP to point to the start of the stored data. 1194bool 1195EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1196{ 1197#if 0 1198 // ARM pseudo code... 1199 if (ConditionPassed()) 1200 { 1201 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1202 address = SP - imm32; 1203 SP = SP - imm32; 1204 if single_regs then 1205 for r = 0 to regs-1 1206 MemA[address,4] = S[d+r]; address = address+4; 1207 else 1208 for r = 0 to regs-1 1209 // Store as two word-aligned words in the correct order for current endianness. 1210 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1211 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1212 address = address+8; 1213 } 1214#endif 1215 1216 bool success = false; 1217 const uint32_t opcode = OpcodeAsUnsigned (&success); 1218 if (!success) 1219 return false; 1220 1221 if (ConditionPassed()) 1222 { 1223 const uint32_t addr_byte_size = GetAddressByteSize(); 1224 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1225 if (!success) 1226 return false; 1227 bool single_regs; 1228 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1229 uint32_t imm32; // stack offset 1230 uint32_t regs; // number of registers 1231 switch (encoding) { 1232 case eEncodingT1: 1233 case eEncodingA1: 1234 single_regs = false; 1235 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1236 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1237 // If UInt(imm8) is odd, see "FSTMX". 1238 regs = Bits32(opcode, 7, 0) / 2; 1239 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1240 if (regs == 0 || regs > 16 || (d + regs) > 32) 1241 return false; 1242 break; 1243 case eEncodingT2: 1244 case eEncodingA2: 1245 single_regs = true; 1246 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1247 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1248 regs = Bits32(opcode, 7, 0); 1249 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1250 if (regs == 0 || regs > 16 || (d + regs) > 32) 1251 return false; 1252 break; 1253 default: 1254 return false; 1255 } 1256 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1257 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1258 addr_t sp_offset = imm32; 1259 addr_t addr = sp - sp_offset; 1260 uint32_t i; 1261 1262 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 1263 for (i=d; i<regs; ++i) 1264 { 1265 context.arg1 = start_reg + i; // arg1 in the context is the DWARF register number 1266 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1267 // uint64_t to accommodate 64-bit registers. 1268 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 1269 if (!success) 1270 return false; 1271 if (!WriteMemoryUnsigned (context, addr, reg_value, reg_byte_size)) 1272 return false; 1273 addr += reg_byte_size; 1274 } 1275 1276 context.type = EmulateInstruction::eContextAdjustStackPointer; 1277 context.arg0 = eRegisterKindGeneric; 1278 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1279 context.arg2 = -sp_offset; 1280 1281 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1282 return false; 1283 } 1284 return true; 1285} 1286 1287// Vector Pop loads multiple extension registers from the stack. 1288// It also updates SP to point just above the loaded data. 1289bool 1290EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1291{ 1292#if 0 1293 // ARM pseudo code... 1294 if (ConditionPassed()) 1295 { 1296 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1297 address = SP; 1298 SP = SP + imm32; 1299 if single_regs then 1300 for r = 0 to regs-1 1301 S[d+r] = MemA[address,4]; address = address+4; 1302 else 1303 for r = 0 to regs-1 1304 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1305 // Combine the word-aligned words in the correct order for current endianness. 1306 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1307 } 1308#endif 1309 1310 bool success = false; 1311 const uint32_t opcode = OpcodeAsUnsigned (&success); 1312 if (!success) 1313 return false; 1314 1315 if (ConditionPassed()) 1316 { 1317 const uint32_t addr_byte_size = GetAddressByteSize(); 1318 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1319 if (!success) 1320 return false; 1321 bool single_regs; 1322 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1323 uint32_t imm32; // stack offset 1324 uint32_t regs; // number of registers 1325 switch (encoding) { 1326 case eEncodingT1: 1327 case eEncodingA1: 1328 single_regs = false; 1329 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1330 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1331 // If UInt(imm8) is odd, see "FLDMX". 1332 regs = Bits32(opcode, 7, 0) / 2; 1333 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1334 if (regs == 0 || regs > 16 || (d + regs) > 32) 1335 return false; 1336 break; 1337 case eEncodingT2: 1338 case eEncodingA2: 1339 single_regs = true; 1340 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1341 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1342 regs = Bits32(opcode, 7, 0); 1343 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1344 if (regs == 0 || regs > 16 || (d + regs) > 32) 1345 return false; 1346 break; 1347 default: 1348 return false; 1349 } 1350 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1351 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1352 addr_t sp_offset = imm32; 1353 addr_t addr = sp; 1354 uint32_t i; 1355 uint64_t data; // uint64_t to accomodate 64-bit registers. 1356 1357 EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 }; 1358 for (i=d; i<regs; ++i) 1359 { 1360 context.arg1 = start_reg + i; // arg1 in the context is the DWARF register number 1361 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1362 data = ReadMemoryUnsigned(context, addr, reg_byte_size, 0, &success); 1363 if (!success) 1364 return false; 1365 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data)) 1366 return false; 1367 addr += reg_byte_size; 1368 } 1369 1370 context.type = EmulateInstruction::eContextAdjustStackPointer; 1371 context.arg0 = eRegisterKindGeneric; 1372 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1373 context.arg2 = sp_offset; 1374 1375 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1376 return false; 1377 } 1378 return true; 1379} 1380 1381// SVC (previously SWI) 1382bool 1383EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1384{ 1385#if 0 1386 // ARM pseudo code... 1387 if (ConditionPassed()) 1388 { 1389 EncodingSpecificOperations(); 1390 CallSupervisor(); 1391 } 1392#endif 1393 1394 bool success = false; 1395 const uint32_t opcode = OpcodeAsUnsigned (&success); 1396 if (!success) 1397 return false; 1398 1399 if (ConditionPassed()) 1400 { 1401 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1402 addr_t lr; // next instruction address 1403 if (!success) 1404 return false; 1405 uint32_t imm32; // the immediate constant 1406 uint32_t mode; // ARM or Thumb mode 1407 switch (encoding) { 1408 case eEncodingT1: 1409 lr = (pc + 2) | 1u; // return address 1410 imm32 = Bits32(opcode, 7, 0); 1411 mode = eModeThumb; 1412 break; 1413 case eEncodingA1: 1414 lr = pc + 4; // return address 1415 imm32 = Bits32(opcode, 23, 0); 1416 mode = eModeARM; 1417 break; 1418 default: 1419 return false; 1420 } 1421 EmulateInstruction::Context context = { EmulateInstruction::eContextSupervisorCall, mode, imm32, 0}; 1422 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1423 return false; 1424 } 1425 return true; 1426} 1427 1428// If Then makes up to four following instructions (the IT block) conditional. 1429bool 1430EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1431{ 1432#if 0 1433 // ARM pseudo code... 1434 EncodingSpecificOperations(); 1435 ITSTATE.IT<7:0> = firstcond:mask; 1436#endif 1437 1438 bool success = false; 1439 const uint32_t opcode = OpcodeAsUnsigned (&success); 1440 if (!success) 1441 return false; 1442 1443 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1444 return true; 1445} 1446 1447// Branch causes a branch to a target address. 1448bool 1449EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1450{ 1451#if 0 1452 // ARM pseudo code... 1453 if (ConditionPassed()) 1454 { 1455 EncodingSpecificOperations(); 1456 BranchWritePC(PC + imm32); 1457 } 1458#endif 1459 1460 bool success = false; 1461 const uint32_t opcode = OpcodeAsUnsigned (&success); 1462 if (!success) 1463 return false; 1464 1465 if (ConditionPassed()) 1466 { 1467 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 1468 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1469 if (!success) 1470 return false; 1471 addr_t target; // target address 1472 int32_t imm32; // PC-relative offset 1473 switch (encoding) { 1474 case eEncodingT1: 1475 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1476 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1477 target = pc + 4 + imm32; 1478 context.arg1 = 4 + imm32; // signed offset 1479 context.arg2 = eModeThumb; // target instruction set 1480 break; 1481 case eEncodingT2: 1482 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1483 target = pc + 4 + imm32; 1484 context.arg1 = 4 + imm32; // signed offset 1485 context.arg2 = eModeThumb; // target instruction set 1486 break; 1487 case eEncodingT3: 1488 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1489 { 1490 uint32_t S = Bit32(opcode, 26); 1491 uint32_t imm6 = Bits32(opcode, 21, 16); 1492 uint32_t J1 = Bit32(opcode, 13); 1493 uint32_t J2 = Bit32(opcode, 11); 1494 uint32_t imm11 = Bits32(opcode, 10, 0); 1495 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 1496 imm32 = llvm::SignExtend32<21>(imm21); 1497 target = pc + 4 + imm32; 1498 context.arg1 = eModeThumb; // target instruction set 1499 context.arg2 = 4 + imm32; // signed offset 1500 break; 1501 } 1502 case eEncodingT4: 1503 { 1504 uint32_t S = Bit32(opcode, 26); 1505 uint32_t imm10 = Bits32(opcode, 25, 16); 1506 uint32_t J1 = Bit32(opcode, 13); 1507 uint32_t J2 = Bit32(opcode, 11); 1508 uint32_t imm11 = Bits32(opcode, 10, 0); 1509 uint32_t I1 = !(J1 ^ S); 1510 uint32_t I2 = !(J2 ^ S); 1511 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1512 imm32 = llvm::SignExtend32<25>(imm25); 1513 target = pc + 4 + imm32; 1514 context.arg1 = eModeThumb; // target instruction set 1515 context.arg2 = 4 + imm32; // signed offset 1516 break; 1517 } 1518 case eEncodingA1: 1519 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1520 target = pc + 8 + imm32; 1521 context.arg1 = eModeARM; // target instruction set 1522 context.arg2 = 8 + imm32; // signed offset 1523 break; 1524 default: 1525 return false; 1526 } 1527 if (!BranchWritePC(context, target)) 1528 return false; 1529 } 1530 return true; 1531} 1532 1533// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 1534// zero and conditionally branch forward a constant value. They do not affect the condition flags. 1535// CBNZ, CBZ 1536bool 1537EmulateInstructionARM::EmulateCB (ARMEncoding encoding) 1538{ 1539#if 0 1540 // ARM pseudo code... 1541 EncodingSpecificOperations(); 1542 if nonzero ^ IsZero(R[n]) then 1543 BranchWritePC(PC + imm32); 1544#endif 1545 1546 bool success = false; 1547 const uint32_t opcode = OpcodeAsUnsigned (&success); 1548 if (!success) 1549 return false; 1550 1551 // Read the register value from the operand register Rn. 1552 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success); 1553 if (!success) 1554 return false; 1555 1556 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 1557 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1558 if (!success) 1559 return false; 1560 1561 addr_t target; // target address 1562 uint32_t imm32; // PC-relative offset to branch forward 1563 bool nonzero; 1564 switch (encoding) { 1565 case eEncodingT1: 1566 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 1567 nonzero = BitIsSet(opcode, 11); 1568 target = pc + 4 + imm32; 1569 context.arg1 = 4 + imm32; // signed offset 1570 context.arg2 = eModeThumb; // target instruction set 1571 break; 1572 default: 1573 return false; 1574 } 1575 if (nonzero ^ (reg_val == 0)) 1576 if (!BranchWritePC(context, target)) 1577 return false; 1578 1579 return true; 1580} 1581 1582// ADD <Rdn>, <Rm> 1583// where <Rdn> the destination register is also the first operand register 1584// and <Rm> is the second operand register. 1585bool 1586EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) 1587{ 1588#if 0 1589 // ARM pseudo code... 1590 if ConditionPassed() then 1591 EncodingSpecificOperations(); 1592 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1593 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 1594 if d == 15 then 1595 ALUWritePC(result); // setflags is always FALSE here 1596 else 1597 R[d] = result; 1598 if setflags then 1599 APSR.N = result<31>; 1600 APSR.Z = IsZeroBit(result); 1601 APSR.C = carry; 1602 APSR.V = overflow; 1603#endif 1604 1605 bool success = false; 1606 const uint32_t opcode = OpcodeAsUnsigned (&success); 1607 if (!success) 1608 return false; 1609 1610 if (ConditionPassed()) 1611 { 1612 uint32_t Rd, Rn, Rm; 1613 //bool setflags = false; 1614 switch (encoding) 1615 { 1616 case eEncodingT2: 1617 // setflags = FALSE 1618 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1619 Rm = Bits32(opcode, 6, 3); 1620 if (Rn == 15 && Rm == 15) 1621 return false; 1622 break; 1623 default: 1624 return false; 1625 } 1626 1627 int32_t result, val1, val2; 1628 // Read the first operand. 1629 if (Rn == 15) 1630 val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1631 else 1632 val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1633 if (!success) 1634 return false; 1635 1636 // Read the second operand. 1637 if (Rm == 15) 1638 val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1639 else 1640 val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1641 if (!success) 1642 return false; 1643 1644 result = val1 + val2; 1645 EmulateInstruction::Context context = { EmulateInstruction::eContextImmediate, 1646 result, 1647 0, 1648 0 }; 1649 1650 if (Rd == 15) 1651 { 1652 if (!ALUWritePC (context, result)) 1653 return false; 1654 } 1655 else 1656 { 1657 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, result)) 1658 return false; 1659 } 1660 } 1661 return true; 1662} 1663 1664bool 1665EmulateInstructionARM::EmulateCmpRnImm (ARMEncoding encoding) 1666{ 1667#if 0 1668 // ARM pseudo code... 1669 if ConditionPassed() then 1670 EncodingSpecificOperations(); 1671 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 1672 APSR.N = result<31>; 1673 APSR.Z = IsZeroBit(result); 1674 APSR.C = carry; 1675 APSR.V = overflow; 1676#endif 1677 1678 bool success = false; 1679 const uint32_t opcode = OpcodeAsUnsigned (&success); 1680 if (!success) 1681 return false; 1682 1683 uint32_t Rn; // the first operand 1684 uint32_t imm32; // the immediate value to be compared with 1685 switch (encoding) { 1686 case eEncodingT1: 1687 Rn = Bits32(opcode, 10, 8); 1688 imm32 = Bits32(opcode, 7, 0); 1689 break; 1690 default: 1691 return false; 1692 } 1693 // Read the register value from the operand register Rn. 1694 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1695 if (!success) 1696 return false; 1697 1698 EmulateInstruction::Context context = { EmulateInstruction::eContextImmediate, 0, 0, 0}; 1699 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 1700 m_new_inst_cpsr = m_inst_cpsr; 1701 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(res.result, CPSR_N)); 1702 SetBit32(m_new_inst_cpsr, CPSR_Z, res.result == 0 ? 1 : 0); 1703 SetBit32(m_new_inst_cpsr, CPSR_C, res.carry_out); 1704 SetBit32(m_new_inst_cpsr, CPSR_V, res.overflow); 1705 if (m_new_inst_cpsr != m_inst_cpsr) 1706 { 1707 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1708 return false; 1709 } 1710 return true; 1711} 1712 1713// LDM loads multiple registers from consecutive memory locations, using an 1714// address from a base register. Optionally the addres just above the highest of those locations 1715// can be written back to the base register. 1716bool 1717EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 1718{ 1719#if 0 1720 // ARM pseudo code... 1721 if ConditionPassed() 1722 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 1723 address = R[n]; 1724 1725 for i = 0 to 14 1726 if registers<i> == '1' then 1727 R[i] = MemA[address, 4]; address = address + 4; 1728 if registers<15> == '1' then 1729 LoadWritePC (MemA[address, 4]); 1730 1731 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 1732 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1733 1734#endif 1735 1736 bool success = false; 1737 const uint32_t opcode = OpcodeAsUnsigned (&success); 1738 if (!success) 1739 return false; 1740 1741 if (ConditionPassed()) 1742 { 1743 uint32_t n; 1744 uint32_t registers = 0; 1745 bool wback; 1746 const uint32_t addr_byte_size = GetAddressByteSize(); 1747 switch (encoding) 1748 { 1749 case eEncodingT1: 1750 n = Bits32 (opcode, 10, 8); 1751 registers = Bits32 (opcode, 7, 0); 1752 wback = BitIsClear (registers, n); 1753 // if BitCount(registers) < 1 then UNPREDICTABLE; 1754 if (BitCount(registers) < 1) 1755 return false; 1756 break; 1757 case eEncodingT2: 1758 n = Bits32 (opcode, 19, 16); 1759 registers = Bits32 (opcode, 15, 0); 1760 wback = BitIsSet (opcode, 21); 1761 if ((n == 15) 1762 || (BitCount (registers) < 2) 1763 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 1764 return false; 1765 if (BitIsSet (registers, 15) 1766 && m_it_session.InITBlock() 1767 && !m_it_session.LastInITBlock()) 1768 return false; 1769 if (wback 1770 && BitIsSet (registers, n)) 1771 return false; 1772 break; 1773 case eEncodingA1: 1774 n = Bits32 (opcode, 19, 16); 1775 registers = Bits32 (opcode, 15, 0); 1776 wback = BitIsSet (opcode, 21); 1777 if ((n == 15) 1778 || (BitCount (registers) < 1)) 1779 return false; 1780 break; 1781 default: 1782 return false; 1783 } 1784 1785 int32_t offset = 0; 1786 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1787 if (!success) 1788 return false; 1789 1790 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1791 eRegisterKindDWARF, 1792 dwarf_r0 + n, 1793 offset }; 1794 1795 for (int i = 0; i < 14; ++i) 1796 { 1797 if (BitIsSet (registers, i)) 1798 { 1799 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1800 context.arg2 = offset; 1801 if (wback && (n == 13)) // Pop Instruction 1802 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1803 1804 // R[i] = MemA [address, 4]; address = address + 4; 1805 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 1806 if (!success) 1807 return false; 1808 1809 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1810 return false; 1811 1812 offset += addr_byte_size; 1813 } 1814 } 1815 1816 if (BitIsSet (registers, 15)) 1817 { 1818 //LoadWritePC (MemA [address, 4]); 1819 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1820 context.arg2 = offset; 1821 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 1822 if (!success) 1823 return false; 1824 // In ARMv5T and above, this is an interworking branch. 1825 if (!LoadWritePC(context, data)) 1826 return false; 1827 } 1828 1829 if (wback && BitIsClear (registers, n)) 1830 { 1831 addr_t offset = addr_byte_size * BitCount (registers); 1832 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1833 context.arg2 = offset; 1834 1835 // R[n] = R[n] + 4 * BitCount (registers) 1836 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 1837 return false; 1838 } 1839 if (wback && BitIsSet (registers, n)) 1840 // R[n] bits(32) UNKNOWN; 1841 return false; //I'm not convinced this is the right thing to do here... 1842 } 1843 return true; 1844} 1845 1846bool 1847EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 1848{ 1849#if 0 1850 // ARM pseudo code... 1851 if ConditionPassed() then 1852 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 1853 address = R[n] - 4*BitCount(registers); 1854 1855 for i = 0 to 14 1856 if registers<i> == ’1’ then 1857 R[i] = MemA[address,4]; address = address + 4; 1858 if registers<15> == ’1’ then 1859 LoadWritePC(MemA[address,4]); 1860 1861 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 1862 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1863#endif 1864 1865 bool success = false; 1866 const uint32_t opcode = OpcodeAsUnsigned (&success); 1867 if (!success) 1868 return false; 1869 1870 if (ConditionPassed()) 1871 { 1872 uint32_t n; 1873 uint32_t registers = 0; 1874 bool wback; 1875 const uint32_t addr_byte_size = GetAddressByteSize(); 1876 switch (encoding) 1877 { 1878 case eEncodingT1: 1879 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 1880 n = Bits32 (opcode, 19, 16); 1881 registers = Bits32 (opcode, 15, 0); 1882 wback = BitIsSet (opcode, 21); 1883 1884 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 1885 if ((n == 15) 1886 || (BitCount (registers) < 2) 1887 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 1888 return false; 1889 1890 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 1891 if (BitIsSet (registers, 15) 1892 && m_it_session.InITBlock() 1893 && !m_it_session.LastInITBlock()) 1894 return false; 1895 1896 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 1897 if (wback && BitIsSet (registers, n)) 1898 return false; 1899 1900 break; 1901 1902 case eEncodingA1: 1903 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 1904 n = Bits32 (opcode, 19, 16); 1905 registers = Bits32 (opcode, 15, 0); 1906 wback = BitIsSet (opcode, 21); 1907 1908 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 1909 if ((n == 15) || (BitCount (registers) < 1)) 1910 return false; 1911 1912 break; 1913 1914 default: 1915 return false; 1916 } 1917 1918 int32_t offset = 0; 1919 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) 1920 - (addr_byte_size * BitCount (registers)); 1921 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1922 eRegisterKindDWARF, 1923 dwarf_r0 + n, 1924 offset }; 1925 1926 for (int i = 0; i < 14; ++i) 1927 { 1928 if (BitIsSet (registers, i)) 1929 { 1930 // R[i] = MemA[address,4]; address = address + 4; 1931 context.arg2 = offset; 1932 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1933 if (!success) 1934 return false; 1935 1936 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1937 return false; 1938 1939 offset += addr_byte_size; 1940 } 1941 } 1942 1943 // if registers<15> == ’1’ then 1944 // LoadWritePC(MemA[address,4]); 1945 if (BitIsSet (registers, 15)) 1946 { 1947 context.arg2 = offset; 1948 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1949 if (!success) 1950 return false; 1951 // In ARMv5T and above, this is an interworking branch. 1952 if (!LoadWritePC(context, data)) 1953 return false; 1954 } 1955 1956 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 1957 if (wback && BitIsClear (registers, n)) 1958 { 1959 context.arg2 = offset; 1960 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1961 if (!success) 1962 return false; 1963 addr = addr - (addr_byte_size * BitCount (registers)); 1964 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 1965 return false; 1966 } 1967 1968 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1969 if (wback && BitIsSet (registers, n)) 1970 return false; // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN. 1971 } 1972 return true; 1973} 1974 1975bool 1976EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 1977{ 1978#if 0 1979 if ConditionPassed() then 1980 EncodingSpecificOperations(); 1981 address = R[n] + 4; 1982 1983 for i = 0 to 14 1984 if registers<i> == ’1’ then 1985 R[i] = MemA[address,4]; address = address + 4; 1986 if registers<15> == ’1’ then 1987 LoadWritePC(MemA[address,4]); 1988 1989 if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 1990 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 1991#endif 1992 1993 bool success = false; 1994 const uint32_t opcode = OpcodeAsUnsigned (&success); 1995 if (!success) 1996 return false; 1997 1998 if (ConditionPassed()) 1999 { 2000 uint32_t n; 2001 uint32_t registers = 0; 2002 bool wback; 2003 const uint32_t addr_byte_size = GetAddressByteSize(); 2004 switch (encoding) 2005 { 2006 case eEncodingA1: 2007 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2008 n = Bits32 (opcode, 19, 16); 2009 registers = Bits32 (opcode, 15, 0); 2010 wback = BitIsSet (opcode, 21); 2011 2012 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2013 if ((n == 15) || (BitCount (registers) < 1)) 2014 return false; 2015 2016 break; 2017 default: 2018 return false; 2019 } 2020 // address = R[n] + 4; 2021 2022 int32_t offset = 0; 2023 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) + addr_byte_size; 2024 2025 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 2026 eRegisterKindDWARF, 2027 dwarf_r0 + n, 2028 offset }; 2029 2030 for (int i = 0; i < 14; ++i) 2031 { 2032 if (BitIsSet (registers, i)) 2033 { 2034 // R[i] = MemA[address,4]; address = address + 4; 2035 2036 context.arg2 = offset; 2037 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2038 if (!success) 2039 return false; 2040 2041 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2042 return false; 2043 2044 offset += addr_byte_size; 2045 } 2046 } 2047 2048 // if registers<15> == ’1’ then 2049 // LoadWritePC(MemA[address,4]); 2050 if (BitIsSet (registers, 15)) 2051 { 2052 context.arg2 = offset; 2053 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2054 if (!success) 2055 return false; 2056 // In ARMv5T and above, this is an interworking branch. 2057 if (!LoadWritePC(context, data)) 2058 return false; 2059 } 2060 2061 // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2062 if (wback && BitIsClear (registers, n)) 2063 { 2064 context.arg2 = offset; 2065 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2066 if (!success) 2067 return false; 2068 addr = addr + (addr_byte_size * BitCount (registers)); 2069 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2070 return false; 2071 } 2072 2073 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2074 if (wback && BitIsSet (registers, n)) 2075 return false; // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN. 2076 } 2077 return true; 2078} 2079 2080// Load Register (immediate) calculates an address from a base register value and 2081// an immediate offset, loads a word from memory, and writes to a register. 2082// LDR (immediate, Thumb) 2083bool 2084EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 2085{ 2086#if 0 2087 // ARM pseudo code... 2088 if (ConditionPassed()) 2089 { 2090 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 2091 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2092 address = if index then offset_addr else R[n]; 2093 data = MemU[address,4]; 2094 if wback then R[n] = offset_addr; 2095 if t == 15 then 2096 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 2097 elsif UnalignedSupport() || address<1:0> = '00' then 2098 R[t] = data; 2099 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 2100 } 2101#endif 2102 2103 bool success = false; 2104 const uint32_t opcode = OpcodeAsUnsigned (&success); 2105 if (!success) 2106 return false; 2107 2108 if (ConditionPassed()) 2109 { 2110 uint32_t Rt; // the destination register 2111 uint32_t Rn; // the base register 2112 uint32_t imm32; // the immediate offset used to form the address 2113 addr_t offset_addr; // the offset address 2114 addr_t address; // the calculated address 2115 uint32_t data; // the literal data value from memory load 2116 bool add, index, wback; 2117 switch (encoding) { 2118 case eEncodingT1: 2119 Rt = Bits32(opcode, 5, 3); 2120 Rn = Bits32(opcode, 2, 0); 2121 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 2122 // index = TRUE; add = TRUE; wback = FALSE 2123 add = true; 2124 index = true; 2125 wback = false; 2126 break; 2127 default: 2128 return false; 2129 } 2130 uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2131 if (!success) 2132 return false; 2133 if (add) 2134 offset_addr = base + imm32; 2135 else 2136 offset_addr = base - imm32; 2137 2138 address = (index ? offset_addr : base); 2139 2140 if (wback) 2141 { 2142 EmulateInstruction::Context ctx = { EmulateInstruction::eContextRegisterPlusOffset, 2143 eRegisterKindDWARF, 2144 dwarf_r0 + Rn, 2145 (int32_t) (offset_addr - base)}; 2146 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 2147 return false; 2148 } 2149 2150 // Prepare to write to the Rt register. 2151 EmulateInstruction::Context context = {EmulateInstruction::eContextImmediate, 2152 0, 2153 0, 2154 0}; 2155 2156 // Read memory from the address. 2157 data = ReadMemoryUnsigned(context, address, 4, 0, &success); 2158 if (!success) 2159 return false; 2160 context.arg0 = data; 2161 2162 if (Rt == 15) 2163 { 2164 if (Bits32(address, 1, 0) == 0) 2165 { 2166 if (!LoadWritePC(context, data)) 2167 return false; 2168 } 2169 else 2170 return false; 2171 } 2172 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 2173 { 2174 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 2175 return false; 2176 } 2177 else 2178 return false; 2179 } 2180 return true; 2181} 2182 2183EmulateInstructionARM::ARMOpcode* 2184EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 2185{ 2186 static ARMOpcode 2187 g_arm_opcodes[] = 2188 { 2189 //---------------------------------------------------------------------- 2190 // Prologue instructions 2191 //---------------------------------------------------------------------- 2192 2193 // push register(s) 2194 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 2195 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" }, 2196 2197 // set r7 to point to a stack offset 2198 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" }, 2199 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 2200 // copy the stack pointer to ip 2201 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" }, 2202 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" }, 2203 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 2204 2205 // adjust the stack pointer 2206 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 2207 2208 // push one register 2209 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 2210 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 2211 2212 // vector push consecutive extension register(s) 2213 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 2214 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 2215 2216 //---------------------------------------------------------------------- 2217 // Epilogue instructions 2218 //---------------------------------------------------------------------- 2219 2220 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 2221 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 2222 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 2223 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 2224 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 2225 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"}, 2226 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 2227 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 2228 2229 //---------------------------------------------------------------------- 2230 // Supervisor Call (previously Software Interrupt) 2231 //---------------------------------------------------------------------- 2232 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 2233 2234 //---------------------------------------------------------------------- 2235 // Branch instructions 2236 //---------------------------------------------------------------------- 2237 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 2238 2239 //---------------------------------------------------------------------- 2240 // Load instructions 2241 //---------------------------------------------------------------------- 2242 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 2243 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 2244 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" } 2245 2246 }; 2247 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 2248 2249 for (size_t i=0; i<k_num_arm_opcodes; ++i) 2250 { 2251 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 2252 return &g_arm_opcodes[i]; 2253 } 2254 return NULL; 2255} 2256 2257 2258EmulateInstructionARM::ARMOpcode* 2259EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 2260{ 2261 2262 static ARMOpcode 2263 g_thumb_opcodes[] = 2264 { 2265 //---------------------------------------------------------------------- 2266 // Prologue instructions 2267 //---------------------------------------------------------------------- 2268 2269 // push register(s) 2270 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 2271 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" }, 2272 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" }, 2273 2274 // set r7 to point to a stack offset 2275 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" }, 2276 // copy the stack pointer to r7 2277 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" }, 2278 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 2279 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" }, 2280 2281 // PC relative load into register (see also EmulateAddSPRm) 2282 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRdPCRelative, "ldr <Rd>, [PC, #imm]"}, 2283 2284 // adjust the stack pointer 2285 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 2286 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 2287 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 2288 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 2289 2290 // vector push consecutive extension register(s) 2291 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 2292 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 2293 2294 //---------------------------------------------------------------------- 2295 // Epilogue instructions 2296 //---------------------------------------------------------------------- 2297 2298 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 2299 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 2300 // J1 == J2 == 1 2301 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 2302 // J1 == J2 == 1 2303 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 2304 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 2305 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" }, 2306 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" }, 2307 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 2308 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 2309 2310 //---------------------------------------------------------------------- 2311 // Supervisor Call (previously Software Interrupt) 2312 //---------------------------------------------------------------------- 2313 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 2314 2315 //---------------------------------------------------------------------- 2316 // If Then makes up to four following instructions conditional. 2317 //---------------------------------------------------------------------- 2318 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 2319 2320 //---------------------------------------------------------------------- 2321 // Branch instructions 2322 //---------------------------------------------------------------------- 2323 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 2324 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 2325 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 2326 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 2327 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 2328 // compare and branch 2329 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 2330 2331 //---------------------------------------------------------------------- 2332 // Data-processing instructions 2333 //---------------------------------------------------------------------- 2334 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 2335 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdnRm, "add <Rdn>, <Rm>"}, 2336 // move from high register to high register 2337 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "mov<c> <Rd>, <Rm>"}, 2338 // move from low register to low register 2339 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "movs <Rd>, <Rm>"}, 2340 // compare a register with immediate 2341 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCmpRnImm, "cmp<c> <Rn>, #imm8"}, 2342 2343 //---------------------------------------------------------------------- 2344 // Load instructions 2345 //---------------------------------------------------------------------- 2346 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 2347 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 2348 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 2349 { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"} 2350 2351 }; 2352 2353 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 2354 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 2355 { 2356 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 2357 return &g_thumb_opcodes[i]; 2358 } 2359 return NULL; 2360} 2361 2362bool 2363EmulateInstructionARM::SetTargetTriple (const ConstString &triple) 2364{ 2365 m_arm_isa = 0; 2366 const char *triple_cstr = triple.GetCString(); 2367 if (triple_cstr) 2368 { 2369 const char *dash = ::strchr (triple_cstr, '-'); 2370 if (dash) 2371 { 2372 std::string arch (triple_cstr, dash); 2373 const char *arch_cstr = arch.c_str(); 2374 if (strcasecmp(arch_cstr, "armv4t") == 0) 2375 m_arm_isa = ARMv4T; 2376 else if (strcasecmp(arch_cstr, "armv4") == 0) 2377 m_arm_isa = ARMv4; 2378 else if (strcasecmp(arch_cstr, "armv5tej") == 0) 2379 m_arm_isa = ARMv5TEJ; 2380 else if (strcasecmp(arch_cstr, "armv5te") == 0) 2381 m_arm_isa = ARMv5TE; 2382 else if (strcasecmp(arch_cstr, "armv5t") == 0) 2383 m_arm_isa = ARMv5T; 2384 else if (strcasecmp(arch_cstr, "armv6k") == 0) 2385 m_arm_isa = ARMv6K; 2386 else if (strcasecmp(arch_cstr, "armv6") == 0) 2387 m_arm_isa = ARMv6; 2388 else if (strcasecmp(arch_cstr, "armv6t2") == 0) 2389 m_arm_isa = ARMv6T2; 2390 else if (strcasecmp(arch_cstr, "armv7") == 0) 2391 m_arm_isa = ARMv7; 2392 else if (strcasecmp(arch_cstr, "armv8") == 0) 2393 m_arm_isa = ARMv8; 2394 } 2395 } 2396 return m_arm_isa != 0; 2397} 2398 2399 2400bool 2401EmulateInstructionARM::ReadInstruction () 2402{ 2403 bool success = false; 2404 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 2405 if (success) 2406 { 2407 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 2408 if (success) 2409 { 2410 Context read_inst_context = {eContextReadOpcode, 0, 0}; 2411 if (m_inst_cpsr & MASK_CPSR_T) 2412 { 2413 m_inst_mode = eModeThumb; 2414 uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success); 2415 2416 if (success) 2417 { 2418 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 2419 { 2420 m_inst.opcode_type = eOpcode16; 2421 m_inst.opcode.inst16 = thumb_opcode; 2422 } 2423 else 2424 { 2425 m_inst.opcode_type = eOpcode32; 2426 m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success); 2427 } 2428 } 2429 } 2430 else 2431 { 2432 m_inst_mode = eModeARM; 2433 m_inst.opcode_type = eOpcode32; 2434 m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success); 2435 } 2436 } 2437 } 2438 if (!success) 2439 { 2440 m_inst_mode = eModeInvalid; 2441 m_inst_pc = LLDB_INVALID_ADDRESS; 2442 } 2443 return success; 2444} 2445 2446uint32_t 2447EmulateInstructionARM::ArchVersion () 2448{ 2449 return m_arm_isa; 2450} 2451 2452bool 2453EmulateInstructionARM::ConditionPassed () 2454{ 2455 if (m_inst_cpsr == 0) 2456 return false; 2457 2458 const uint32_t cond = CurrentCond (); 2459 2460 if (cond == UINT32_MAX) 2461 return false; 2462 2463 bool result = false; 2464 switch (UnsignedBits(cond, 3, 1)) 2465 { 2466 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 2467 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 2468 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 2469 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 2470 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 2471 case 5: 2472 { 2473 bool n = (m_inst_cpsr & MASK_CPSR_N); 2474 bool v = (m_inst_cpsr & MASK_CPSR_V); 2475 result = n == v; 2476 } 2477 break; 2478 case 6: 2479 { 2480 bool n = (m_inst_cpsr & MASK_CPSR_N); 2481 bool v = (m_inst_cpsr & MASK_CPSR_V); 2482 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 2483 } 2484 break; 2485 case 7: 2486 result = true; 2487 break; 2488 } 2489 2490 if (cond & 1) 2491 result = !result; 2492 return result; 2493} 2494 2495uint32_t 2496EmulateInstructionARM::CurrentCond () 2497{ 2498 switch (m_inst_mode) 2499 { 2500 default: 2501 case eModeInvalid: 2502 break; 2503 2504 case eModeARM: 2505 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 2506 2507 case eModeThumb: 2508 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 2509 // 'cond' field of the encoding. 2510 if (m_inst.opcode_type == eOpcode16 && 2511 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 2512 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 2513 { 2514 return Bits32(m_inst.opcode.inst16, 11, 7); 2515 } 2516 else if (m_inst.opcode_type == eOpcode32 && 2517 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 2518 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 2519 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 2520 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 2521 { 2522 return Bits32(m_inst.opcode.inst32, 25, 22); 2523 } 2524 2525 return m_it_session.GetCond(); 2526 } 2527 return UINT32_MAX; // Return invalid value 2528} 2529 2530bool 2531EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 2532{ 2533 addr_t target; 2534 2535 // Check the current instruction set. 2536 if (CurrentInstrSet() == eModeARM) 2537 target = addr & 0xfffffffc; 2538 else 2539 target = addr & 0xfffffffe; 2540 2541 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 2542 return false; 2543 2544 return true; 2545} 2546 2547// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 2548bool 2549EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 2550{ 2551 addr_t target; 2552 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 2553 // we want to record it and issue a WriteRegister callback so the clients 2554 // can track the mode changes accordingly. 2555 bool cpsr_changed = false; 2556 2557 if (BitIsSet(addr, 0)) 2558 { 2559 if (CurrentInstrSet() != eModeThumb) 2560 { 2561 SelectInstrSet(eModeThumb); 2562 cpsr_changed = true; 2563 } 2564 target = addr & 0xfffffffe; 2565 context.arg2 = eModeThumb; 2566 } 2567 else if (BitIsClear(addr, 1)) 2568 { 2569 if (CurrentInstrSet() != eModeARM) 2570 { 2571 SelectInstrSet(eModeARM); 2572 cpsr_changed = true; 2573 } 2574 target = addr & 0xfffffffc; 2575 context.arg2 = eModeARM; 2576 } 2577 else 2578 return false; // address<1:0> == '10' => UNPREDICTABLE 2579 2580 if (cpsr_changed) 2581 { 2582 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2583 return false; 2584 } 2585 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 2586 return false; 2587 2588 return true; 2589} 2590 2591// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 2592bool 2593EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 2594{ 2595 if (ArchVersion() >= ARMv5T) 2596 return BXWritePC(context, addr); 2597 else 2598 return BranchWritePC((const Context)context, addr); 2599} 2600 2601// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 2602bool 2603EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 2604{ 2605 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 2606 return BXWritePC(context, addr); 2607 else 2608 return BranchWritePC((const Context)context, addr); 2609} 2610 2611EmulateInstructionARM::Mode 2612EmulateInstructionARM::CurrentInstrSet () 2613{ 2614 return m_inst_mode; 2615} 2616 2617// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 2618// ReadInstruction() is performed. This function has a side effect of updating 2619// the m_new_inst_cpsr member variable if necessary. 2620bool 2621EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 2622{ 2623 m_new_inst_cpsr = m_inst_cpsr; 2624 switch (arm_or_thumb) 2625 { 2626 default: 2627 return false; 2628 eModeARM: 2629 // Clear the T bit. 2630 m_new_inst_cpsr &= ~MASK_CPSR_T; 2631 break; 2632 eModeThumb: 2633 // Set the T bit. 2634 m_new_inst_cpsr |= MASK_CPSR_T; 2635 break; 2636 } 2637 return true; 2638} 2639 2640// This function returns TRUE if the processor currently provides support for 2641// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 2642// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 2643bool 2644EmulateInstructionARM::UnalignedSupport() 2645{ 2646 return (ArchVersion() >= ARMv7); 2647} 2648 2649// The main addition and subtraction instructions can produce status information 2650// about both unsigned carry and signed overflow conditions. This status 2651// information can be used to synthesize multi-word additions and subtractions. 2652EmulateInstructionARM::AddWithCarryResult 2653EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 2654{ 2655 uint32_t result; 2656 uint8_t carry_out; 2657 uint8_t overflow; 2658 2659 uint64_t unsigned_sum = x + y + carry_in; 2660 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 2661 2662 result = UnsignedBits(unsigned_sum, 31, 0); 2663 carry_out = (result == unsigned_sum ? 0 : 1); 2664 overflow = ((int32_t)result == signed_sum ? 0 : 1); 2665 2666 AddWithCarryResult res = { result, carry_out, overflow }; 2667 return res; 2668} 2669 2670bool 2671EmulateInstructionARM::EvaluateInstruction () 2672{ 2673 // Advance the ITSTATE bits to their values for the next instruction. 2674 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 2675 m_it_session.ITAdvance(); 2676 2677 return false; 2678} 2679