EmulateInstructionARM.cpp revision 672f3110bdd2a088f10ae9f246aaab5daa7b0fa1
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// Convenient macro definitions. 27#define APSR_C Bit32(m_inst_cpsr, CPSR_C_POS) 28#define APSR_V Bit32(m_inst_cpsr, CPSR_V_POS) 29 30#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 31 32//---------------------------------------------------------------------- 33// 34// ITSession implementation 35// 36//---------------------------------------------------------------------- 37 38// A8.6.50 39// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 40static unsigned short CountITSize(unsigned ITMask) { 41 // First count the trailing zeros of the IT mask. 42 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 43 if (TZ > 3) 44 { 45 printf("Encoding error: IT Mask '0000'\n"); 46 return 0; 47 } 48 return (4 - TZ); 49} 50 51// Init ITState. Note that at least one bit is always 1 in mask. 52bool ITSession::InitIT(unsigned short bits7_0) 53{ 54 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 55 if (ITCounter == 0) 56 return false; 57 58 // A8.6.50 IT 59 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 60 if (FirstCond == 0xF) 61 { 62 printf("Encoding error: IT FirstCond '1111'\n"); 63 return false; 64 } 65 if (FirstCond == 0xE && ITCounter != 1) 66 { 67 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 68 return false; 69 } 70 71 ITState = bits7_0; 72 return true; 73} 74 75// Update ITState if necessary. 76void ITSession::ITAdvance() 77{ 78 assert(ITCounter); 79 --ITCounter; 80 if (ITCounter == 0) 81 ITState = 0; 82 else 83 { 84 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 85 SetBits32(ITState, 4, 0, NewITState4_0); 86 } 87} 88 89// Return true if we're inside an IT Block. 90bool ITSession::InITBlock() 91{ 92 return ITCounter != 0; 93} 94 95// Return true if we're the last instruction inside an IT Block. 96bool ITSession::LastInITBlock() 97{ 98 return ITCounter == 1; 99} 100 101// Get condition bits for the current thumb instruction. 102uint32_t ITSession::GetCond() 103{ 104 if (InITBlock()) 105 return Bits32(ITState, 7, 4); 106 else 107 return COND_AL; 108} 109 110// ARM constants used during decoding 111#define REG_RD 0 112#define LDM_REGLIST 1 113#define SP_REG 13 114#define LR_REG 14 115#define PC_REG 15 116#define PC_REGLIST_BIT 0x8000 117 118#define ARMv4 (1u << 0) 119#define ARMv4T (1u << 1) 120#define ARMv5T (1u << 2) 121#define ARMv5TE (1u << 3) 122#define ARMv5TEJ (1u << 4) 123#define ARMv6 (1u << 5) 124#define ARMv6K (1u << 6) 125#define ARMv6T2 (1u << 7) 126#define ARMv7 (1u << 8) 127#define ARMv8 (1u << 9) 128#define ARMvAll (0xffffffffu) 129 130#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 131#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 132#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 133#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 134 135//---------------------------------------------------------------------- 136// 137// EmulateInstructionARM implementation 138// 139//---------------------------------------------------------------------- 140 141void 142EmulateInstructionARM::Initialize () 143{ 144} 145 146void 147EmulateInstructionARM::Terminate () 148{ 149} 150 151// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 152bool 153EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 154{ 155 EmulateInstruction::Context context; 156 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 157 context.SetNoArgs (); 158 159 uint32_t random_data = rand (); 160 const uint32_t addr_byte_size = GetAddressByteSize(); 161 162 if (!MemAWrite (context, address, random_data, addr_byte_size)) 163 return false; 164 165 return true; 166} 167 168// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 169bool 170EmulateInstructionARM::WriteBits32Unknown (int n) 171{ 172 EmulateInstruction::Context context; 173 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 174 context.SetNoArgs (); 175 176 bool success; 177 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 178 179 if (!success) 180 return false; 181 182 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 183 return false; 184 185 return true; 186} 187 188// Push Multiple Registers stores multiple registers to the stack, storing to 189// consecutive memory locations ending just below the address in SP, and updates 190// SP to point to the start of the stored data. 191bool 192EmulateInstructionARM::EmulatePUSH (ARMEncoding encoding) 193{ 194#if 0 195 // ARM pseudo code... 196 if (ConditionPassed()) 197 { 198 EncodingSpecificOperations(); 199 NullCheckIfThumbEE(13); 200 address = SP - 4*BitCount(registers); 201 202 for (i = 0 to 14) 203 { 204 if (registers<i> == ’1’) 205 { 206 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 207 MemA[address,4] = bits(32) UNKNOWN; 208 else 209 MemA[address,4] = R[i]; 210 address = address + 4; 211 } 212 } 213 214 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 215 MemA[address,4] = PCStoreValue(); 216 217 SP = SP - 4*BitCount(registers); 218 } 219#endif 220 221 bool success = false; 222 const uint32_t opcode = OpcodeAsUnsigned (&success); 223 if (!success) 224 return false; 225 226 if (ConditionPassed()) 227 { 228 const uint32_t addr_byte_size = GetAddressByteSize(); 229 const addr_t sp = ReadCoreReg (SP_REG, &success); 230 if (!success) 231 return false; 232 uint32_t registers = 0; 233 uint32_t Rt; // the source register 234 switch (encoding) { 235 case eEncodingT1: 236 registers = Bits32(opcode, 7, 0); 237 // The M bit represents LR. 238 if (Bit32(opcode, 8)) 239 registers |= (1u << 14); 240 // if BitCount(registers) < 1 then UNPREDICTABLE; 241 if (BitCount(registers) < 1) 242 return false; 243 break; 244 case eEncodingT2: 245 // Ignore bits 15 & 13. 246 registers = Bits32(opcode, 15, 0) & ~0xa000; 247 // if BitCount(registers) < 2 then UNPREDICTABLE; 248 if (BitCount(registers) < 2) 249 return false; 250 break; 251 case eEncodingT3: 252 Rt = Bits32(opcode, 15, 12); 253 // if BadReg(t) then UNPREDICTABLE; 254 if (BadReg(Rt)) 255 return false; 256 registers = (1u << Rt); 257 break; 258 case eEncodingA1: 259 registers = Bits32(opcode, 15, 0); 260 // Instead of return false, let's handle the following case as well, 261 // which amounts to pushing one reg onto the full descending stacks. 262 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 263 break; 264 case eEncodingA2: 265 Rt = Bits32(opcode, 15, 12); 266 // if t == 13 then UNPREDICTABLE; 267 if (Rt == dwarf_sp) 268 return false; 269 registers = (1u << Rt); 270 break; 271 default: 272 return false; 273 } 274 addr_t sp_offset = addr_byte_size * BitCount (registers); 275 addr_t addr = sp - sp_offset; 276 uint32_t i; 277 278 EmulateInstruction::Context context; 279 context.type = EmulateInstruction::eContextPushRegisterOnStack; 280 Register dwarf_reg; 281 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 282 for (i=0; i<15; ++i) 283 { 284 if (BitIsSet (registers, i)) 285 { 286 dwarf_reg.num = dwarf_r0 + i; 287 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 288 uint32_t reg_value = ReadCoreReg(i, &success); 289 if (!success) 290 return false; 291 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 292 return false; 293 addr += addr_byte_size; 294 } 295 } 296 297 if (BitIsSet (registers, 15)) 298 { 299 dwarf_reg.num = dwarf_pc; 300 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 301 const uint32_t pc = ReadCoreReg(PC_REG, &success); 302 if (!success) 303 return false; 304 if (!MemAWrite (context, addr, pc, addr_byte_size)) 305 return false; 306 } 307 308 context.type = EmulateInstruction::eContextAdjustStackPointer; 309 context.SetImmediateSigned (-sp_offset); 310 311 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 312 return false; 313 } 314 return true; 315} 316 317// Pop Multiple Registers loads multiple registers from the stack, loading from 318// consecutive memory locations staring at the address in SP, and updates 319// SP to point just above the loaded data. 320bool 321EmulateInstructionARM::EmulatePOP (ARMEncoding encoding) 322{ 323#if 0 324 // ARM pseudo code... 325 if (ConditionPassed()) 326 { 327 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 328 address = SP; 329 for i = 0 to 14 330 if registers<i> == ‘1’ then 331 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 332 if registers<15> == ‘1’ then 333 if UnalignedAllowed then 334 LoadWritePC(MemU[address,4]); 335 else 336 LoadWritePC(MemA[address,4]); 337 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 338 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 339 } 340#endif 341 342 bool success = false; 343 const uint32_t opcode = OpcodeAsUnsigned (&success); 344 if (!success) 345 return false; 346 347 if (ConditionPassed()) 348 { 349 const uint32_t addr_byte_size = GetAddressByteSize(); 350 const addr_t sp = ReadCoreReg (SP_REG, &success); 351 if (!success) 352 return false; 353 uint32_t registers = 0; 354 uint32_t Rt; // the destination register 355 switch (encoding) { 356 case eEncodingT1: 357 registers = Bits32(opcode, 7, 0); 358 // The P bit represents PC. 359 if (Bit32(opcode, 8)) 360 registers |= (1u << 15); 361 // if BitCount(registers) < 1 then UNPREDICTABLE; 362 if (BitCount(registers) < 1) 363 return false; 364 break; 365 case eEncodingT2: 366 // Ignore bit 13. 367 registers = Bits32(opcode, 15, 0) & ~0x2000; 368 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 369 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 370 return false; 371 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 372 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 373 return false; 374 break; 375 case eEncodingT3: 376 Rt = Bits32(opcode, 15, 12); 377 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 378 if (Rt == 13) 379 return false; 380 if (Rt == 15 && InITBlock() && !LastInITBlock()) 381 return false; 382 registers = (1u << Rt); 383 break; 384 case eEncodingA1: 385 registers = Bits32(opcode, 15, 0); 386 // Instead of return false, let's handle the following case as well, 387 // which amounts to popping one reg from the full descending stacks. 388 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 389 390 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 391 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 392 return false; 393 break; 394 case eEncodingA2: 395 Rt = Bits32(opcode, 15, 12); 396 // if t == 13 then UNPREDICTABLE; 397 if (Rt == dwarf_sp) 398 return false; 399 registers = (1u << Rt); 400 break; 401 default: 402 return false; 403 } 404 addr_t sp_offset = addr_byte_size * BitCount (registers); 405 addr_t addr = sp; 406 uint32_t i, data; 407 408 EmulateInstruction::Context context; 409 context.type = EmulateInstruction::eContextPopRegisterOffStack; 410 Register dwarf_reg; 411 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 412 for (i=0; i<15; ++i) 413 { 414 if (BitIsSet (registers, i)) 415 { 416 dwarf_reg.num = dwarf_r0 + i; 417 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 418 data = MemARead(context, addr, 4, 0, &success); 419 if (!success) 420 return false; 421 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 422 return false; 423 addr += addr_byte_size; 424 } 425 } 426 427 if (BitIsSet (registers, 15)) 428 { 429 dwarf_reg.num = dwarf_pc; 430 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 431 data = MemARead(context, addr, 4, 0, &success); 432 if (!success) 433 return false; 434 // In ARMv5T and above, this is an interworking branch. 435 if (!LoadWritePC(context, data)) 436 return false; 437 addr += addr_byte_size; 438 } 439 440 context.type = EmulateInstruction::eContextAdjustStackPointer; 441 context.SetImmediateSigned (sp_offset); 442 443 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 444 return false; 445 } 446 return true; 447} 448 449// Set r7 or ip to point to saved value residing within the stack. 450// ADD (SP plus immediate) 451bool 452EmulateInstructionARM::EmulateADDRdSPImm (ARMEncoding encoding) 453{ 454#if 0 455 // ARM pseudo code... 456 if (ConditionPassed()) 457 { 458 EncodingSpecificOperations(); 459 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 460 if d == 15 then 461 ALUWritePC(result); // setflags is always FALSE here 462 else 463 R[d] = result; 464 if setflags then 465 APSR.N = result<31>; 466 APSR.Z = IsZeroBit(result); 467 APSR.C = carry; 468 APSR.V = overflow; 469 } 470#endif 471 472 bool success = false; 473 const uint32_t opcode = OpcodeAsUnsigned (&success); 474 if (!success) 475 return false; 476 477 if (ConditionPassed()) 478 { 479 const addr_t sp = ReadCoreReg (SP_REG, &success); 480 if (!success) 481 return false; 482 uint32_t Rd; // the destination register 483 uint32_t imm32; 484 switch (encoding) { 485 case eEncodingT1: 486 Rd = 7; 487 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 488 break; 489 case eEncodingA1: 490 Rd = Bits32(opcode, 15, 12); 491 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 492 break; 493 default: 494 return false; 495 } 496 addr_t sp_offset = imm32; 497 addr_t addr = sp + sp_offset; // a pointer to the stack area 498 499 EmulateInstruction::Context context; 500 context.type = EmulateInstruction::eContextRegisterPlusOffset; 501 Register sp_reg; 502 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 503 context.SetRegisterPlusOffset (sp_reg, sp_offset); 504 505 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 506 return false; 507 } 508 return true; 509} 510 511// Set r7 or ip to the current stack pointer. 512// MOV (register) 513bool 514EmulateInstructionARM::EmulateMOVRdSP (ARMEncoding encoding) 515{ 516#if 0 517 // ARM pseudo code... 518 if (ConditionPassed()) 519 { 520 EncodingSpecificOperations(); 521 result = R[m]; 522 if d == 15 then 523 ALUWritePC(result); // setflags is always FALSE here 524 else 525 R[d] = result; 526 if setflags then 527 APSR.N = result<31>; 528 APSR.Z = IsZeroBit(result); 529 // APSR.C unchanged 530 // APSR.V unchanged 531 } 532#endif 533 534 bool success = false; 535 //const uint32_t opcode = OpcodeAsUnsigned (&success); 536 //if (!success) 537 // return false; 538 539 if (ConditionPassed()) 540 { 541 const addr_t sp = ReadCoreReg (SP_REG, &success); 542 if (!success) 543 return false; 544 uint32_t Rd; // the destination register 545 switch (encoding) { 546 case eEncodingT1: 547 Rd = 7; 548 break; 549 case eEncodingA1: 550 Rd = 12; 551 break; 552 default: 553 return false; 554 } 555 556 EmulateInstruction::Context context; 557 context.type = EmulateInstruction::eContextRegisterPlusOffset; 558 Register sp_reg; 559 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 560 context.SetRegisterPlusOffset (sp_reg, 0); 561 562 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 563 return false; 564 } 565 return true; 566} 567 568// Move from high register (r8-r15) to low register (r0-r7). 569// MOV (register) 570bool 571EmulateInstructionARM::EmulateMOVLowHigh (ARMEncoding encoding) 572{ 573 return EmulateMOVRdRm (encoding); 574} 575 576// Move from register to register. 577// MOV (register) 578bool 579EmulateInstructionARM::EmulateMOVRdRm (ARMEncoding encoding) 580{ 581#if 0 582 // ARM pseudo code... 583 if (ConditionPassed()) 584 { 585 EncodingSpecificOperations(); 586 result = R[m]; 587 if d == 15 then 588 ALUWritePC(result); // setflags is always FALSE here 589 else 590 R[d] = result; 591 if setflags then 592 APSR.N = result<31>; 593 APSR.Z = IsZeroBit(result); 594 // APSR.C unchanged 595 // APSR.V unchanged 596 } 597#endif 598 599 bool success = false; 600 const uint32_t opcode = OpcodeAsUnsigned (&success); 601 if (!success) 602 return false; 603 604 if (ConditionPassed()) 605 { 606 uint32_t Rm; // the source register 607 uint32_t Rd; // the destination register 608 bool setflags; 609 switch (encoding) { 610 case eEncodingT1: 611 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 612 Rm = Bits32(opcode, 6, 3); 613 setflags = false; 614 if (Rd == 15 && InITBlock() && !LastInITBlock()) 615 return false; 616 break; 617 case eEncodingT2: 618 Rd = Bits32(opcode, 2, 0); 619 Rm = Bits32(opcode, 5, 3); 620 setflags = true; 621 if (InITBlock()) 622 return false; 623 break; 624 case eEncodingT3: 625 Rd = Bits32(opcode, 11, 8); 626 Rm = Bits32(opcode, 3, 0); 627 setflags = BitIsSet(opcode, 20); 628 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 629 if (setflags && (BadReg(Rd) || BadReg(Rm))) 630 return false; 631 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 632 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 633 return false; 634 break; 635 case eEncodingA1: 636 Rd = Bits32(opcode, 15, 12); 637 Rm = Bits32(opcode, 3, 0); 638 setflags = BitIsSet(opcode, 20); 639 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 640 // TODO: Emulate SUBS PC, LR and related instructions. 641 if (Rd == 15 && setflags) 642 return false; 643 break; 644 default: 645 return false; 646 } 647 uint32_t result = ReadCoreReg(Rm, &success); 648 if (!success) 649 return false; 650 651 // The context specifies that Rm is to be moved into Rd. 652 EmulateInstruction::Context context; 653 context.type = EmulateInstruction::eContextRegisterPlusOffset; 654 Register dwarf_reg; 655 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 656 context.SetRegisterPlusOffset (dwarf_reg, 0); 657 658 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 659 return false; 660 } 661 return true; 662} 663 664// Move (immediate) writes an immediate value to the destination register. It 665// can optionally update the condition flags based on the value. 666// MOV (immediate) 667bool 668EmulateInstructionARM::EmulateMOVRdImm (ARMEncoding encoding) 669{ 670#if 0 671 // ARM pseudo code... 672 if (ConditionPassed()) 673 { 674 EncodingSpecificOperations(); 675 result = imm32; 676 if d == 15 then // Can only occur for ARM encoding 677 ALUWritePC(result); // setflags is always FALSE here 678 else 679 R[d] = result; 680 if setflags then 681 APSR.N = result<31>; 682 APSR.Z = IsZeroBit(result); 683 APSR.C = carry; 684 // APSR.V unchanged 685 } 686#endif 687 bool success = false; 688 const uint32_t opcode = OpcodeAsUnsigned (&success); 689 if (!success) 690 return false; 691 692 if (ConditionPassed()) 693 { 694 uint32_t Rd; // the destination register 695 uint32_t imm32; // the immediate value to be written to Rd 696 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 697 bool setflags; 698 switch (encoding) { 699 case eEncodingT1: 700 Rd = Bits32(opcode, 10, 8); 701 setflags = !InITBlock(); 702 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 703 carry = APSR_C; 704 break; 705 case eEncodingT2: 706 Rd = Bits32(opcode, 11, 8); 707 setflags = BitIsSet(opcode, 20); 708 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 709 if (BadReg(Rd)) 710 return false; 711 break; 712 default: 713 return false; 714 } 715 uint32_t result = imm32; 716 717 // The context specifies that an immediate is to be moved into Rd. 718 EmulateInstruction::Context context; 719 context.type = EmulateInstruction::eContextImmediate; 720 context.SetNoArgs (); 721 722 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 723 return false; 724 } 725 return true; 726} 727 728// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 729// It can optionally update the condition flags based on the value. 730bool 731EmulateInstructionARM::EmulateMVNImm (ARMEncoding encoding) 732{ 733#if 0 734 // ARM pseudo code... 735 if (ConditionPassed()) 736 { 737 EncodingSpecificOperations(); 738 result = NOT(imm32); 739 if d == 15 then // Can only occur for ARM encoding 740 ALUWritePC(result); // setflags is always FALSE here 741 else 742 R[d] = result; 743 if setflags then 744 APSR.N = result<31>; 745 APSR.Z = IsZeroBit(result); 746 APSR.C = carry; 747 // APSR.V unchanged 748 } 749#endif 750 bool success = false; 751 const uint32_t opcode = OpcodeAsUnsigned (&success); 752 if (!success) 753 return false; 754 755 if (ConditionPassed()) 756 { 757 uint32_t Rd; // the destination register 758 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 759 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 760 bool setflags; 761 switch (encoding) { 762 case eEncodingT1: 763 Rd = Bits32(opcode, 11, 8); 764 setflags = BitIsSet(opcode, 20); 765 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 766 break; 767 case eEncodingA1: 768 Rd = Bits32(opcode, 15, 12); 769 setflags = BitIsSet(opcode, 20); 770 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 771 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 772 // TODO: Emulate SUBS PC, LR and related instructions. 773 if (Rd == 15 && setflags) 774 return false; 775 break; 776 default: 777 return false; 778 } 779 uint32_t result = ~imm32; 780 781 // The context specifies that an immediate is to be moved into Rd. 782 EmulateInstruction::Context context; 783 context.type = EmulateInstruction::eContextImmediate; 784 context.SetNoArgs (); 785 786 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 787 return false; 788 } 789 return true; 790} 791 792// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 793// It can optionally update the condition flags based on the result. 794bool 795EmulateInstructionARM::EmulateMVNReg (ARMEncoding encoding) 796{ 797#if 0 798 // ARM pseudo code... 799 if (ConditionPassed()) 800 { 801 EncodingSpecificOperations(); 802 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 803 result = NOT(shifted); 804 if d == 15 then // Can only occur for ARM encoding 805 ALUWritePC(result); // setflags is always FALSE here 806 else 807 R[d] = result; 808 if setflags then 809 APSR.N = result<31>; 810 APSR.Z = IsZeroBit(result); 811 APSR.C = carry; 812 // APSR.V unchanged 813 } 814#endif 815 816 bool success = false; 817 const uint32_t opcode = OpcodeAsUnsigned (&success); 818 if (!success) 819 return false; 820 821 if (ConditionPassed()) 822 { 823 uint32_t Rm; // the source register 824 uint32_t Rd; // the destination register 825 ARM_ShifterType shift_t; 826 uint32_t shift_n; // the shift applied to the value read from Rm 827 bool setflags; 828 uint32_t carry; // the carry bit after the shift operation 829 switch (encoding) { 830 case eEncodingT1: 831 Rd = Bits32(opcode, 2, 0); 832 Rm = Bits32(opcode, 5, 3); 833 setflags = !InITBlock(); 834 shift_t = SRType_LSL; 835 shift_n = 0; 836 if (InITBlock()) 837 return false; 838 break; 839 case eEncodingT2: 840 Rd = Bits32(opcode, 11, 8); 841 Rm = Bits32(opcode, 3, 0); 842 setflags = BitIsSet(opcode, 20); 843 shift_n = DecodeImmShiftThumb(opcode, shift_t); 844 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 845 if (BadReg(Rd) || BadReg(Rm)) 846 return false; 847 break; 848 case eEncodingA1: 849 Rd = Bits32(opcode, 15, 12); 850 Rm = Bits32(opcode, 3, 0); 851 setflags = BitIsSet(opcode, 20); 852 shift_n = DecodeImmShiftARM(opcode, shift_t); 853 break; 854 default: 855 return false; 856 } 857 uint32_t value = ReadCoreReg(Rm, &success); 858 if (!success) 859 return false; 860 861 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry); 862 uint32_t result = ~shifted; 863 864 // The context specifies that an immediate is to be moved into Rd. 865 EmulateInstruction::Context context; 866 context.type = EmulateInstruction::eContextImmediate; 867 context.SetNoArgs (); 868 869 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 870 return false; 871 } 872 return true; 873} 874 875// PC relative immediate load into register, possibly followed by ADD (SP plus register). 876// LDR (literal) 877bool 878EmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding) 879{ 880#if 0 881 // ARM pseudo code... 882 if (ConditionPassed()) 883 { 884 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 885 base = Align(PC,4); 886 address = if add then (base + imm32) else (base - imm32); 887 data = MemU[address,4]; 888 if t == 15 then 889 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 890 elsif UnalignedSupport() || address<1:0> = ‘00’ then 891 R[t] = data; 892 else // Can only apply before ARMv7 893 if CurrentInstrSet() == InstrSet_ARM then 894 R[t] = ROR(data, 8*UInt(address<1:0>)); 895 else 896 R[t] = bits(32) UNKNOWN; 897 } 898#endif 899 900 bool success = false; 901 const uint32_t opcode = OpcodeAsUnsigned (&success); 902 if (!success) 903 return false; 904 905 if (ConditionPassed()) 906 { 907 const uint32_t pc = ReadCoreReg(PC_REG, &success); 908 if (!success) 909 return false; 910 911 // PC relative immediate load context 912 EmulateInstruction::Context context; 913 context.type = EmulateInstruction::eContextRegisterPlusOffset; 914 Register pc_reg; 915 pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 916 context.SetRegisterPlusOffset (pc_reg, 0); 917 918 uint32_t Rt; // the destination register 919 uint32_t imm32; // immediate offset from the PC 920 bool add; // +imm32 or -imm32? 921 addr_t base; // the base address 922 addr_t address; // the PC relative address 923 uint32_t data; // the literal data value from the PC relative load 924 switch (encoding) { 925 case eEncodingT1: 926 Rt = Bits32(opcode, 10, 8); 927 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 928 add = true; 929 break; 930 case eEncodingT2: 931 Rt = Bits32(opcode, 15, 12); 932 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 933 add = BitIsSet(opcode, 23); 934 if (Rt == 15 && InITBlock() && !LastInITBlock()) 935 return false; 936 break; 937 default: 938 return false; 939 } 940 941 base = Align(pc, 4); 942 if (add) 943 address = base + imm32; 944 else 945 address = base - imm32; 946 947 context.SetRegisterPlusOffset(pc_reg, address - base); 948 data = MemURead(context, address, 4, 0, &success); 949 if (!success) 950 return false; 951 952 if (Rt == 15) 953 { 954 if (Bits32(address, 1, 0) == 0) 955 { 956 // In ARMv5T and above, this is an interworking branch. 957 if (!LoadWritePC(context, data)) 958 return false; 959 } 960 else 961 return false; 962 } 963 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 964 { 965 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 966 return false; 967 } 968 else // We don't handle ARM for now. 969 return false; 970 971 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 972 return false; 973 } 974 return true; 975} 976 977// An add operation to adjust the SP. 978// ADD (SP plus immediate) 979bool 980EmulateInstructionARM::EmulateADDSPImm (ARMEncoding encoding) 981{ 982#if 0 983 // ARM pseudo code... 984 if (ConditionPassed()) 985 { 986 EncodingSpecificOperations(); 987 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 988 if d == 15 then // Can only occur for ARM encoding 989 ALUWritePC(result); // setflags is always FALSE here 990 else 991 R[d] = result; 992 if setflags then 993 APSR.N = result<31>; 994 APSR.Z = IsZeroBit(result); 995 APSR.C = carry; 996 APSR.V = overflow; 997 } 998#endif 999 1000 bool success = false; 1001 const uint32_t opcode = OpcodeAsUnsigned (&success); 1002 if (!success) 1003 return false; 1004 1005 if (ConditionPassed()) 1006 { 1007 const addr_t sp = ReadCoreReg (SP_REG, &success); 1008 if (!success) 1009 return false; 1010 uint32_t imm32; // the immediate operand 1011 switch (encoding) { 1012 case eEncodingT2: 1013 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1014 break; 1015 default: 1016 return false; 1017 } 1018 addr_t sp_offset = imm32; 1019 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1020 1021 EmulateInstruction::Context context; 1022 context.type = EmulateInstruction::eContextAdjustStackPointer; 1023 context.SetImmediateSigned (sp_offset); 1024 1025 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1026 return false; 1027 } 1028 return true; 1029} 1030 1031// An add operation to adjust the SP. 1032// ADD (SP plus register) 1033bool 1034EmulateInstructionARM::EmulateADDSPRm (ARMEncoding encoding) 1035{ 1036#if 0 1037 // ARM pseudo code... 1038 if (ConditionPassed()) 1039 { 1040 EncodingSpecificOperations(); 1041 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1042 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 1043 if d == 15 then 1044 ALUWritePC(result); // setflags is always FALSE here 1045 else 1046 R[d] = result; 1047 if setflags then 1048 APSR.N = result<31>; 1049 APSR.Z = IsZeroBit(result); 1050 APSR.C = carry; 1051 APSR.V = overflow; 1052 } 1053#endif 1054 1055 bool success = false; 1056 const uint32_t opcode = OpcodeAsUnsigned (&success); 1057 if (!success) 1058 return false; 1059 1060 if (ConditionPassed()) 1061 { 1062 const addr_t sp = ReadCoreReg (SP_REG, &success); 1063 if (!success) 1064 return false; 1065 uint32_t Rm; // the second operand 1066 switch (encoding) { 1067 case eEncodingT2: 1068 Rm = Bits32(opcode, 6, 3); 1069 break; 1070 default: 1071 return false; 1072 } 1073 int32_t reg_value = ReadCoreReg(Rm, &success); 1074 if (!success) 1075 return false; 1076 1077 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1078 1079 EmulateInstruction::Context context; 1080 context.type = EmulateInstruction::eContextAdjustStackPointer; 1081 context.SetImmediateSigned (reg_value); 1082 1083 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1084 return false; 1085 } 1086 return true; 1087} 1088 1089// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1090// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1091// from Thumb to ARM. 1092// BLX (immediate) 1093bool 1094EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 1095{ 1096#if 0 1097 // ARM pseudo code... 1098 if (ConditionPassed()) 1099 { 1100 EncodingSpecificOperations(); 1101 if CurrentInstrSet() == InstrSet_ARM then 1102 LR = PC - 4; 1103 else 1104 LR = PC<31:1> : '1'; 1105 if targetInstrSet == InstrSet_ARM then 1106 targetAddress = Align(PC,4) + imm32; 1107 else 1108 targetAddress = PC + imm32; 1109 SelectInstrSet(targetInstrSet); 1110 BranchWritePC(targetAddress); 1111 } 1112#endif 1113 1114 bool success = false; 1115 const uint32_t opcode = OpcodeAsUnsigned (&success); 1116 if (!success) 1117 return false; 1118 1119 if (ConditionPassed()) 1120 { 1121 EmulateInstruction::Context context; 1122 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1123 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1124 if (!success) 1125 return false; 1126 addr_t lr; // next instruction address 1127 addr_t target; // target address 1128 int32_t imm32; // PC-relative offset 1129 switch (encoding) { 1130 case eEncodingT1: 1131 { 1132 lr = pc | 1u; // return address 1133 uint32_t S = Bit32(opcode, 26); 1134 uint32_t imm10 = Bits32(opcode, 25, 16); 1135 uint32_t J1 = Bit32(opcode, 13); 1136 uint32_t J2 = Bit32(opcode, 11); 1137 uint32_t imm11 = Bits32(opcode, 10, 0); 1138 uint32_t I1 = !(J1 ^ S); 1139 uint32_t I2 = !(J2 ^ S); 1140 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1141 imm32 = llvm::SignExtend32<25>(imm25); 1142 target = pc + imm32; 1143 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1144 if (InITBlock() && !LastInITBlock()) 1145 return false; 1146 break; 1147 } 1148 case eEncodingT2: 1149 { 1150 lr = pc | 1u; // return address 1151 uint32_t S = Bit32(opcode, 26); 1152 uint32_t imm10H = Bits32(opcode, 25, 16); 1153 uint32_t J1 = Bit32(opcode, 13); 1154 uint32_t J2 = Bit32(opcode, 11); 1155 uint32_t imm10L = Bits32(opcode, 10, 1); 1156 uint32_t I1 = !(J1 ^ S); 1157 uint32_t I2 = !(J2 ^ S); 1158 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1159 imm32 = llvm::SignExtend32<25>(imm25); 1160 target = Align(pc, 4) + imm32; 1161 context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1162 if (InITBlock() && !LastInITBlock()) 1163 return false; 1164 break; 1165 } 1166 case eEncodingA1: 1167 lr = pc + 4; // return address 1168 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1169 target = Align(pc, 4) + imm32; 1170 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1171 break; 1172 case eEncodingA2: 1173 lr = pc + 4; // return address 1174 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1175 target = pc + imm32; 1176 context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 1177 break; 1178 default: 1179 return false; 1180 } 1181 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1182 return false; 1183 if (!BranchWritePC(context, target)) 1184 return false; 1185 } 1186 return true; 1187} 1188 1189// Branch with Link and Exchange (register) calls a subroutine at an address and 1190// instruction set specified by a register. 1191// BLX (register) 1192bool 1193EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 1194{ 1195#if 0 1196 // ARM pseudo code... 1197 if (ConditionPassed()) 1198 { 1199 EncodingSpecificOperations(); 1200 target = R[m]; 1201 if CurrentInstrSet() == InstrSet_ARM then 1202 next_instr_addr = PC - 4; 1203 LR = next_instr_addr; 1204 else 1205 next_instr_addr = PC - 2; 1206 LR = next_instr_addr<31:1> : ‘1’; 1207 BXWritePC(target); 1208 } 1209#endif 1210 1211 bool success = false; 1212 const uint32_t opcode = OpcodeAsUnsigned (&success); 1213 if (!success) 1214 return false; 1215 1216 if (ConditionPassed()) 1217 { 1218 EmulateInstruction::Context context; 1219 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1220 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1221 addr_t lr; // next instruction address 1222 if (!success) 1223 return false; 1224 uint32_t Rm; // the register with the target address 1225 switch (encoding) { 1226 case eEncodingT1: 1227 lr = (pc - 2) | 1u; // return address 1228 Rm = Bits32(opcode, 6, 3); 1229 // if m == 15 then UNPREDICTABLE; 1230 if (Rm == 15) 1231 return false; 1232 if (InITBlock() && !LastInITBlock()) 1233 return false; 1234 break; 1235 case eEncodingA1: 1236 lr = pc - 4; // return address 1237 Rm = Bits32(opcode, 3, 0); 1238 // if m == 15 then UNPREDICTABLE; 1239 if (Rm == 15) 1240 return false; 1241 break; 1242 default: 1243 return false; 1244 } 1245 addr_t target = ReadCoreReg (Rm, &success); 1246 if (!success) 1247 return false; 1248 Register dwarf_reg; 1249 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1250 context.SetRegister (dwarf_reg); 1251 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1252 return false; 1253 if (!BXWritePC(context, target)) 1254 return false; 1255 } 1256 return true; 1257} 1258 1259// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1260bool 1261EmulateInstructionARM::EmulateBXRm (ARMEncoding encoding) 1262{ 1263#if 0 1264 // ARM pseudo code... 1265 if (ConditionPassed()) 1266 { 1267 EncodingSpecificOperations(); 1268 BXWritePC(R[m]); 1269 } 1270#endif 1271 1272 bool success = false; 1273 const uint32_t opcode = OpcodeAsUnsigned (&success); 1274 if (!success) 1275 return false; 1276 1277 if (ConditionPassed()) 1278 { 1279 EmulateInstruction::Context context; 1280 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1281 uint32_t Rm; // the register with the target address 1282 switch (encoding) { 1283 case eEncodingT1: 1284 Rm = Bits32(opcode, 6, 3); 1285 if (InITBlock() && !LastInITBlock()) 1286 return false; 1287 break; 1288 case eEncodingA1: 1289 Rm = Bits32(opcode, 3, 0); 1290 break; 1291 default: 1292 return false; 1293 } 1294 addr_t target = ReadCoreReg (Rm, &success); 1295 if (!success) 1296 return false; 1297 1298 Register dwarf_reg; 1299 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1300 context.SetRegister (dwarf_reg); 1301 if (!BXWritePC(context, target)) 1302 return false; 1303 } 1304 return true; 1305} 1306 1307// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1308// address and instruction set specified by a register as though it were a BX instruction. 1309// 1310// TODO: Emulate Jazelle architecture? 1311// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1312bool 1313EmulateInstructionARM::EmulateBXJRm (ARMEncoding encoding) 1314{ 1315#if 0 1316 // ARM pseudo code... 1317 if (ConditionPassed()) 1318 { 1319 EncodingSpecificOperations(); 1320 if JMCR.JE == ‘0’ || CurrentInstrSet() == InstrSet_ThumbEE then 1321 BXWritePC(R[m]); 1322 else 1323 if JazelleAcceptsExecution() then 1324 SwitchToJazelleExecution(); 1325 else 1326 SUBARCHITECTURE_DEFINED handler call; 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 EmulateInstruction::Context context; 1338 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1339 uint32_t Rm; // the register with the target address 1340 switch (encoding) { 1341 case eEncodingT1: 1342 Rm = Bits32(opcode, 19, 16); 1343 if (BadReg(Rm)) 1344 return false; 1345 if (InITBlock() && !LastInITBlock()) 1346 return false; 1347 break; 1348 case eEncodingA1: 1349 Rm = Bits32(opcode, 3, 0); 1350 if (Rm == 15) 1351 return false; 1352 break; 1353 default: 1354 return false; 1355 } 1356 addr_t target = ReadCoreReg (Rm, &success); 1357 if (!success) 1358 return false; 1359 1360 Register dwarf_reg; 1361 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1362 context.SetRegister (dwarf_reg); 1363 if (!BXWritePC(context, target)) 1364 return false; 1365 } 1366 return true; 1367} 1368 1369// Set r7 to point to some ip offset. 1370// SUB (immediate) 1371bool 1372EmulateInstructionARM::EmulateSUBR7IPImm (ARMEncoding encoding) 1373{ 1374#if 0 1375 // ARM pseudo code... 1376 if (ConditionPassed()) 1377 { 1378 EncodingSpecificOperations(); 1379 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1380 if d == 15 then // Can only occur for ARM encoding 1381 ALUWritePC(result); // setflags is always FALSE here 1382 else 1383 R[d] = result; 1384 if setflags then 1385 APSR.N = result<31>; 1386 APSR.Z = IsZeroBit(result); 1387 APSR.C = carry; 1388 APSR.V = overflow; 1389 } 1390#endif 1391 1392 bool success = false; 1393 const uint32_t opcode = OpcodeAsUnsigned (&success); 1394 if (!success) 1395 return false; 1396 1397 if (ConditionPassed()) 1398 { 1399 const addr_t ip = ReadCoreReg (12, &success); 1400 if (!success) 1401 return false; 1402 uint32_t imm32; 1403 switch (encoding) { 1404 case eEncodingA1: 1405 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1406 break; 1407 default: 1408 return false; 1409 } 1410 addr_t ip_offset = imm32; 1411 addr_t addr = ip - ip_offset; // the adjusted ip value 1412 1413 EmulateInstruction::Context context; 1414 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1415 Register dwarf_reg; 1416 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 1417 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1418 1419 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1420 return false; 1421 } 1422 return true; 1423} 1424 1425// Set ip to point to some stack offset. 1426// SUB (SP minus immediate) 1427bool 1428EmulateInstructionARM::EmulateSUBIPSPImm (ARMEncoding encoding) 1429{ 1430#if 0 1431 // ARM pseudo code... 1432 if (ConditionPassed()) 1433 { 1434 EncodingSpecificOperations(); 1435 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1436 if d == 15 then // Can only occur for ARM encoding 1437 ALUWritePC(result); // setflags is always FALSE here 1438 else 1439 R[d] = result; 1440 if setflags then 1441 APSR.N = result<31>; 1442 APSR.Z = IsZeroBit(result); 1443 APSR.C = carry; 1444 APSR.V = overflow; 1445 } 1446#endif 1447 1448 bool success = false; 1449 const uint32_t opcode = OpcodeAsUnsigned (&success); 1450 if (!success) 1451 return false; 1452 1453 if (ConditionPassed()) 1454 { 1455 const addr_t sp = ReadCoreReg (SP_REG, &success); 1456 if (!success) 1457 return false; 1458 uint32_t imm32; 1459 switch (encoding) { 1460 case eEncodingA1: 1461 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1462 break; 1463 default: 1464 return false; 1465 } 1466 addr_t sp_offset = imm32; 1467 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1468 1469 EmulateInstruction::Context context; 1470 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1471 Register dwarf_reg; 1472 dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 1473 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1474 1475 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1476 return false; 1477 } 1478 return true; 1479} 1480 1481// This instruction subtracts an immediate value from the SP value, and writes 1482// the result to the destination register. 1483// 1484// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1485bool 1486EmulateInstructionARM::EmulateSUBSPImm (ARMEncoding encoding) 1487{ 1488#if 0 1489 // ARM pseudo code... 1490 if (ConditionPassed()) 1491 { 1492 EncodingSpecificOperations(); 1493 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1494 if d == 15 then // Can only occur for ARM encoding 1495 ALUWritePC(result); // setflags is always FALSE here 1496 else 1497 R[d] = result; 1498 if setflags then 1499 APSR.N = result<31>; 1500 APSR.Z = IsZeroBit(result); 1501 APSR.C = carry; 1502 APSR.V = overflow; 1503 } 1504#endif 1505 1506 bool success = false; 1507 const uint32_t opcode = OpcodeAsUnsigned (&success); 1508 if (!success) 1509 return false; 1510 1511 if (ConditionPassed()) 1512 { 1513 const addr_t sp = ReadCoreReg (SP_REG, &success); 1514 if (!success) 1515 return false; 1516 1517 uint32_t Rd; 1518 bool setflags; 1519 uint32_t imm32; 1520 switch (encoding) { 1521 case eEncodingT1: 1522 Rd = 13; 1523 setflags = false; 1524 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1525 break; 1526 case eEncodingT2: 1527 Rd = Bits32(opcode, 11, 8); 1528 setflags = BitIsSet(opcode, 20); 1529 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1530 if (Rd == 15 && setflags) 1531 return EmulateCMPImm(eEncodingT2); 1532 if (Rd == 15 && !setflags) 1533 return false; 1534 break; 1535 case eEncodingT3: 1536 Rd = Bits32(opcode, 11, 8); 1537 setflags = false; 1538 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1539 if (Rd == 15) 1540 return false; 1541 break; 1542 case eEncodingA1: 1543 Rd = Bits32(opcode, 15, 12); 1544 setflags = BitIsSet(opcode, 20); 1545 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1546 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1547 // TODO: Emulate SUBS PC, LR and related instructions. 1548 if (Rd == 15 && setflags) 1549 return false; 1550 break; 1551 default: 1552 return false; 1553 } 1554 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1555 1556 EmulateInstruction::Context context; 1557 if (Rd == 13) 1558 { 1559 context.type = EmulateInstruction::eContextAdjustStackPointer; 1560 context.SetImmediateSigned (-imm32); // the stack pointer offset 1561 } 1562 else 1563 { 1564 context.type = EmulateInstruction::eContextImmediate; 1565 context.SetNoArgs (); 1566 } 1567 1568 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1569 return false; 1570 } 1571 return true; 1572} 1573 1574// A store operation to the stack that also updates the SP. 1575bool 1576EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1577{ 1578#if 0 1579 // ARM pseudo code... 1580 if (ConditionPassed()) 1581 { 1582 EncodingSpecificOperations(); 1583 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1584 address = if index then offset_addr else R[n]; 1585 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1586 if wback then R[n] = offset_addr; 1587 } 1588#endif 1589 1590 bool success = false; 1591 const uint32_t opcode = OpcodeAsUnsigned (&success); 1592 if (!success) 1593 return false; 1594 1595 if (ConditionPassed()) 1596 { 1597 const uint32_t addr_byte_size = GetAddressByteSize(); 1598 const addr_t sp = ReadCoreReg (SP_REG, &success); 1599 if (!success) 1600 return false; 1601 uint32_t Rt; // the source register 1602 uint32_t imm12; 1603 switch (encoding) { 1604 case eEncodingA1: 1605 Rt = Bits32(opcode, 15, 12); 1606 imm12 = Bits32(opcode, 11, 0); 1607 break; 1608 default: 1609 return false; 1610 } 1611 addr_t sp_offset = imm12; 1612 addr_t addr = sp - sp_offset; 1613 1614 EmulateInstruction::Context context; 1615 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1616 Register dwarf_reg; 1617 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1618 if (Rt != 15) 1619 { 1620 dwarf_reg.num = dwarf_r0 + Rt; 1621 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1622 uint32_t reg_value = ReadCoreReg(Rt, &success); 1623 if (!success) 1624 return false; 1625 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1626 return false; 1627 } 1628 else 1629 { 1630 dwarf_reg.num = dwarf_pc; 1631 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1632 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1633 if (!success) 1634 return false; 1635 if (!MemUWrite (context, addr, pc + 8, addr_byte_size)) 1636 return false; 1637 } 1638 1639 context.type = EmulateInstruction::eContextAdjustStackPointer; 1640 context.SetImmediateSigned (-sp_offset); 1641 1642 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1643 return false; 1644 } 1645 return true; 1646} 1647 1648// Vector Push stores multiple extension registers to the stack. 1649// It also updates SP to point to the start of the stored data. 1650bool 1651EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1652{ 1653#if 0 1654 // ARM pseudo code... 1655 if (ConditionPassed()) 1656 { 1657 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1658 address = SP - imm32; 1659 SP = SP - imm32; 1660 if single_regs then 1661 for r = 0 to regs-1 1662 MemA[address,4] = S[d+r]; address = address+4; 1663 else 1664 for r = 0 to regs-1 1665 // Store as two word-aligned words in the correct order for current endianness. 1666 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1667 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1668 address = address+8; 1669 } 1670#endif 1671 1672 bool success = false; 1673 const uint32_t opcode = OpcodeAsUnsigned (&success); 1674 if (!success) 1675 return false; 1676 1677 if (ConditionPassed()) 1678 { 1679 const uint32_t addr_byte_size = GetAddressByteSize(); 1680 const addr_t sp = ReadCoreReg (SP_REG, &success); 1681 if (!success) 1682 return false; 1683 bool single_regs; 1684 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1685 uint32_t imm32; // stack offset 1686 uint32_t regs; // number of registers 1687 switch (encoding) { 1688 case eEncodingT1: 1689 case eEncodingA1: 1690 single_regs = false; 1691 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1692 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1693 // If UInt(imm8) is odd, see "FSTMX". 1694 regs = Bits32(opcode, 7, 0) / 2; 1695 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1696 if (regs == 0 || regs > 16 || (d + regs) > 32) 1697 return false; 1698 break; 1699 case eEncodingT2: 1700 case eEncodingA2: 1701 single_regs = true; 1702 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1703 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1704 regs = Bits32(opcode, 7, 0); 1705 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1706 if (regs == 0 || regs > 16 || (d + regs) > 32) 1707 return false; 1708 break; 1709 default: 1710 return false; 1711 } 1712 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1713 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1714 addr_t sp_offset = imm32; 1715 addr_t addr = sp - sp_offset; 1716 uint32_t i; 1717 1718 EmulateInstruction::Context context; 1719 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1720 Register dwarf_reg; 1721 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1722 for (i=d; i<regs; ++i) 1723 { 1724 dwarf_reg.num = start_reg + i; 1725 context.SetRegisterPlusOffset ( dwarf_reg, addr - sp); 1726 // uint64_t to accommodate 64-bit registers. 1727 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1728 if (!success) 1729 return false; 1730 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 1731 return false; 1732 addr += reg_byte_size; 1733 } 1734 1735 context.type = EmulateInstruction::eContextAdjustStackPointer; 1736 context.SetImmediateSigned (-sp_offset); 1737 1738 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1739 return false; 1740 } 1741 return true; 1742} 1743 1744// Vector Pop loads multiple extension registers from the stack. 1745// It also updates SP to point just above the loaded data. 1746bool 1747EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1748{ 1749#if 0 1750 // ARM pseudo code... 1751 if (ConditionPassed()) 1752 { 1753 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1754 address = SP; 1755 SP = SP + imm32; 1756 if single_regs then 1757 for r = 0 to regs-1 1758 S[d+r] = MemA[address,4]; address = address+4; 1759 else 1760 for r = 0 to regs-1 1761 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1762 // Combine the word-aligned words in the correct order for current endianness. 1763 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1764 } 1765#endif 1766 1767 bool success = false; 1768 const uint32_t opcode = OpcodeAsUnsigned (&success); 1769 if (!success) 1770 return false; 1771 1772 if (ConditionPassed()) 1773 { 1774 const uint32_t addr_byte_size = GetAddressByteSize(); 1775 const addr_t sp = ReadCoreReg (SP_REG, &success); 1776 if (!success) 1777 return false; 1778 bool single_regs; 1779 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1780 uint32_t imm32; // stack offset 1781 uint32_t regs; // number of registers 1782 switch (encoding) { 1783 case eEncodingT1: 1784 case eEncodingA1: 1785 single_regs = false; 1786 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1787 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1788 // If UInt(imm8) is odd, see "FLDMX". 1789 regs = Bits32(opcode, 7, 0) / 2; 1790 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1791 if (regs == 0 || regs > 16 || (d + regs) > 32) 1792 return false; 1793 break; 1794 case eEncodingT2: 1795 case eEncodingA2: 1796 single_regs = true; 1797 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1798 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1799 regs = Bits32(opcode, 7, 0); 1800 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1801 if (regs == 0 || regs > 16 || (d + regs) > 32) 1802 return false; 1803 break; 1804 default: 1805 return false; 1806 } 1807 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1808 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1809 addr_t sp_offset = imm32; 1810 addr_t addr = sp; 1811 uint32_t i; 1812 uint64_t data; // uint64_t to accomodate 64-bit registers. 1813 1814 EmulateInstruction::Context context; 1815 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1816 Register dwarf_reg; 1817 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1818 for (i=d; i<regs; ++i) 1819 { 1820 dwarf_reg.num = start_reg + i; 1821 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1822 data = MemARead(context, addr, reg_byte_size, 0, &success); 1823 if (!success) 1824 return false; 1825 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1826 return false; 1827 addr += reg_byte_size; 1828 } 1829 1830 context.type = EmulateInstruction::eContextAdjustStackPointer; 1831 context.SetImmediateSigned (sp_offset); 1832 1833 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1834 return false; 1835 } 1836 return true; 1837} 1838 1839// SVC (previously SWI) 1840bool 1841EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1842{ 1843#if 0 1844 // ARM pseudo code... 1845 if (ConditionPassed()) 1846 { 1847 EncodingSpecificOperations(); 1848 CallSupervisor(); 1849 } 1850#endif 1851 1852 bool success = false; 1853 const uint32_t opcode = OpcodeAsUnsigned (&success); 1854 if (!success) 1855 return false; 1856 1857 if (ConditionPassed()) 1858 { 1859 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1860 addr_t lr; // next instruction address 1861 if (!success) 1862 return false; 1863 uint32_t imm32; // the immediate constant 1864 uint32_t mode; // ARM or Thumb mode 1865 switch (encoding) { 1866 case eEncodingT1: 1867 lr = (pc + 2) | 1u; // return address 1868 imm32 = Bits32(opcode, 7, 0); 1869 mode = eModeThumb; 1870 break; 1871 case eEncodingA1: 1872 lr = pc + 4; // return address 1873 imm32 = Bits32(opcode, 23, 0); 1874 mode = eModeARM; 1875 break; 1876 default: 1877 return false; 1878 } 1879 1880 EmulateInstruction::Context context; 1881 context.type = EmulateInstruction::eContextSupervisorCall; 1882 context.SetModeAndImmediate (mode, imm32); 1883 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1884 return false; 1885 } 1886 return true; 1887} 1888 1889// If Then makes up to four following instructions (the IT block) conditional. 1890bool 1891EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1892{ 1893#if 0 1894 // ARM pseudo code... 1895 EncodingSpecificOperations(); 1896 ITSTATE.IT<7:0> = firstcond:mask; 1897#endif 1898 1899 bool success = false; 1900 const uint32_t opcode = OpcodeAsUnsigned (&success); 1901 if (!success) 1902 return false; 1903 1904 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1905 return true; 1906} 1907 1908// Branch causes a branch to a target address. 1909bool 1910EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1911{ 1912#if 0 1913 // ARM pseudo code... 1914 if (ConditionPassed()) 1915 { 1916 EncodingSpecificOperations(); 1917 BranchWritePC(PC + imm32); 1918 } 1919#endif 1920 1921 bool success = false; 1922 const uint32_t opcode = OpcodeAsUnsigned (&success); 1923 if (!success) 1924 return false; 1925 1926 if (ConditionPassed()) 1927 { 1928 EmulateInstruction::Context context; 1929 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1930 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1931 if (!success) 1932 return false; 1933 addr_t target; // target address 1934 int32_t imm32; // PC-relative offset 1935 switch (encoding) { 1936 case eEncodingT1: 1937 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1938 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1939 target = pc + imm32; 1940 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1941 break; 1942 case eEncodingT2: 1943 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1944 target = pc + imm32; 1945 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1946 break; 1947 case eEncodingT3: 1948 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1949 { 1950 uint32_t S = Bit32(opcode, 26); 1951 uint32_t imm6 = Bits32(opcode, 21, 16); 1952 uint32_t J1 = Bit32(opcode, 13); 1953 uint32_t J2 = Bit32(opcode, 11); 1954 uint32_t imm11 = Bits32(opcode, 10, 0); 1955 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 1956 imm32 = llvm::SignExtend32<21>(imm21); 1957 target = pc + imm32; 1958 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1959 break; 1960 } 1961 case eEncodingT4: 1962 { 1963 uint32_t S = Bit32(opcode, 26); 1964 uint32_t imm10 = Bits32(opcode, 25, 16); 1965 uint32_t J1 = Bit32(opcode, 13); 1966 uint32_t J2 = Bit32(opcode, 11); 1967 uint32_t imm11 = Bits32(opcode, 10, 0); 1968 uint32_t I1 = !(J1 ^ S); 1969 uint32_t I2 = !(J2 ^ S); 1970 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1971 imm32 = llvm::SignExtend32<25>(imm25); 1972 target = pc + imm32; 1973 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1974 break; 1975 } 1976 case eEncodingA1: 1977 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1978 target = pc + imm32; 1979 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1980 break; 1981 default: 1982 return false; 1983 } 1984 if (!BranchWritePC(context, target)) 1985 return false; 1986 } 1987 return true; 1988} 1989 1990// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 1991// zero and conditionally branch forward a constant value. They do not affect the condition flags. 1992// CBNZ, CBZ 1993bool 1994EmulateInstructionARM::EmulateCB (ARMEncoding encoding) 1995{ 1996#if 0 1997 // ARM pseudo code... 1998 EncodingSpecificOperations(); 1999 if nonzero ^ IsZero(R[n]) then 2000 BranchWritePC(PC + imm32); 2001#endif 2002 2003 bool success = false; 2004 const uint32_t opcode = OpcodeAsUnsigned (&success); 2005 if (!success) 2006 return false; 2007 2008 // Read the register value from the operand register Rn. 2009 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2010 if (!success) 2011 return false; 2012 2013 EmulateInstruction::Context context; 2014 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2015 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2016 if (!success) 2017 return false; 2018 2019 addr_t target; // target address 2020 uint32_t imm32; // PC-relative offset to branch forward 2021 bool nonzero; 2022 switch (encoding) { 2023 case eEncodingT1: 2024 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2025 nonzero = BitIsSet(opcode, 11); 2026 target = pc + imm32; 2027 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 2028 break; 2029 default: 2030 return false; 2031 } 2032 if (nonzero ^ (reg_val == 0)) 2033 if (!BranchWritePC(context, target)) 2034 return false; 2035 2036 return true; 2037} 2038 2039// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2040// A base register provides a pointer to the table, and a second register supplies an index into the table. 2041// The branch length is twice the value of the byte returned from the table. 2042// 2043// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2044// A base register provides a pointer to the table, and a second register supplies an index into the table. 2045// The branch length is twice the value of the halfword returned from the table. 2046// TBB, TBH 2047bool 2048EmulateInstructionARM::EmulateTB (ARMEncoding encoding) 2049{ 2050#if 0 2051 // ARM pseudo code... 2052 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2053 if is_tbh then 2054 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2055 else 2056 halfwords = UInt(MemU[R[n]+R[m], 1]); 2057 BranchWritePC(PC + 2*halfwords); 2058#endif 2059 2060 bool success = false; 2061 const uint32_t opcode = OpcodeAsUnsigned (&success); 2062 if (!success) 2063 return false; 2064 2065 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2066 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2067 bool is_tbh; // true if table branch halfword 2068 switch (encoding) { 2069 case eEncodingT1: 2070 Rn = Bits32(opcode, 19, 16); 2071 Rm = Bits32(opcode, 3, 0); 2072 is_tbh = BitIsSet(opcode, 4); 2073 if (Rn == 13 || BadReg(Rm)) 2074 return false; 2075 if (InITBlock() && !LastInITBlock()) 2076 return false; 2077 break; 2078 default: 2079 return false; 2080 } 2081 2082 // Read the address of the table from the operand register Rn. 2083 // The PC can be used, in which case the table immediately follows this instruction. 2084 uint32_t base = ReadCoreReg(Rm, &success); 2085 if (!success) 2086 return false; 2087 2088 // the table index 2089 uint32_t index = ReadCoreReg(Rm, &success); 2090 if (!success) 2091 return false; 2092 2093 // the offsetted table address 2094 addr_t addr = base + (is_tbh ? index*2 : index); 2095 2096 // PC-relative offset to branch forward 2097 EmulateInstruction::Context context; 2098 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2099 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2100 if (!success) 2101 return false; 2102 2103 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2104 if (!success) 2105 return false; 2106 2107 // target address 2108 addr_t target = pc + offset; 2109 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2110 context.SetModeAndImmediateSigned (eModeThumb, 4 + offset); 2111 2112 if (!BranchWritePC(context, target)) 2113 return false; 2114 2115 return true; 2116} 2117 2118// This instruction adds an immediate value to a register value, and writes the result to the destination 2119// register. It can optionally update the condition flags based on the result. 2120bool 2121EmulateInstructionARM::EmulateADDImmARM (ARMEncoding encoding) 2122{ 2123#if 0 2124 // ARM pseudo code... 2125 if ConditionPassed() then 2126 EncodingSpecificOperations(); 2127 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2128 if d == 15 then 2129 ALUWritePC(result); // setflags is always FALSE here 2130 else 2131 R[d] = result; 2132 if setflags then 2133 APSR.N = result<31>; 2134 APSR.Z = IsZeroBit(result); 2135 APSR.C = carry; 2136 APSR.V = overflow; 2137#endif 2138 2139 bool success = false; 2140 const uint32_t opcode = OpcodeAsUnsigned (&success); 2141 if (!success) 2142 return false; 2143 2144 if (ConditionPassed()) 2145 { 2146 uint32_t Rd, Rn; 2147 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2148 bool setflags; 2149 switch (encoding) 2150 { 2151 case eEncodingA1: 2152 Rd = Bits32(opcode, 15, 12); 2153 Rn = Bits32(opcode, 19, 16); 2154 setflags = BitIsSet(opcode, 20); 2155 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2156 break; 2157 default: 2158 return false; 2159 } 2160 2161 // Read the first operand. 2162 uint32_t val1 = ReadCoreReg(Rn, &success); 2163 if (!success) 2164 return false; 2165 2166 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2167 2168 EmulateInstruction::Context context; 2169 context.type = EmulateInstruction::eContextImmediate; 2170 context.SetNoArgs (); 2171 2172 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2173 return false; 2174 } 2175 return true; 2176} 2177 2178// This instruction adds a register value and an optionally-shifted register value, and writes the result 2179// to the destination register. It can optionally update the condition flags based on the result. 2180bool 2181EmulateInstructionARM::EmulateADDReg (ARMEncoding encoding) 2182{ 2183#if 0 2184 // ARM pseudo code... 2185 if ConditionPassed() then 2186 EncodingSpecificOperations(); 2187 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2188 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2189 if d == 15 then 2190 ALUWritePC(result); // setflags is always FALSE here 2191 else 2192 R[d] = result; 2193 if setflags then 2194 APSR.N = result<31>; 2195 APSR.Z = IsZeroBit(result); 2196 APSR.C = carry; 2197 APSR.V = overflow; 2198#endif 2199 2200 bool success = false; 2201 const uint32_t opcode = OpcodeAsUnsigned (&success); 2202 if (!success) 2203 return false; 2204 2205 if (ConditionPassed()) 2206 { 2207 uint32_t Rd, Rn, Rm; 2208 ARM_ShifterType shift_t; 2209 uint32_t shift_n; // the shift applied to the value read from Rm 2210 bool setflags; 2211 switch (encoding) 2212 { 2213 case eEncodingT1: 2214 Rd = Bits32(opcode, 2, 0); 2215 Rn = Bits32(opcode, 5, 3); 2216 Rm = Bits32(opcode, 8, 6); 2217 setflags = !InITBlock(); 2218 shift_t = SRType_LSL; 2219 shift_n = 0; 2220 break; 2221 case eEncodingT2: 2222 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2223 Rm = Bits32(opcode, 6, 3); 2224 setflags = false; 2225 shift_t = SRType_LSL; 2226 shift_n = 0; 2227 if (Rn == 15 && Rm == 15) 2228 return false; 2229 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2230 return false; 2231 break; 2232 case eEncodingA1: 2233 Rd = Bits32(opcode, 15, 12); 2234 Rn = Bits32(opcode, 19, 16); 2235 Rm = Bits32(opcode, 3, 0); 2236 setflags = BitIsSet(opcode, 20); 2237 shift_n = DecodeImmShiftARM(opcode, shift_t); 2238 break; 2239 default: 2240 return false; 2241 } 2242 2243 // Read the first operand. 2244 uint32_t val1 = ReadCoreReg(Rn, &success); 2245 if (!success) 2246 return false; 2247 2248 // Read the second operand. 2249 uint32_t val2 = ReadCoreReg(Rm, &success); 2250 if (!success) 2251 return false; 2252 2253 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 2254 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2255 2256 EmulateInstruction::Context context; 2257 context.type = EmulateInstruction::eContextImmediate; 2258 context.SetNoArgs (); 2259 2260 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2261 return false; 2262 } 2263 return true; 2264} 2265 2266// Compare Negative (immediate) adds a register value and an immediate value. 2267// It updates the condition flags based on the result, and discards the result. 2268bool 2269EmulateInstructionARM::EmulateCMNImm (ARMEncoding encoding) 2270{ 2271#if 0 2272 // ARM pseudo code... 2273 if ConditionPassed() then 2274 EncodingSpecificOperations(); 2275 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2276 APSR.N = result<31>; 2277 APSR.Z = IsZeroBit(result); 2278 APSR.C = carry; 2279 APSR.V = overflow; 2280#endif 2281 2282 bool success = false; 2283 const uint32_t opcode = OpcodeAsUnsigned (&success); 2284 if (!success) 2285 return false; 2286 2287 uint32_t Rn; // the first operand 2288 uint32_t imm32; // the immediate value to be compared with 2289 switch (encoding) { 2290 case eEncodingT1: 2291 Rn = Bits32(opcode, 19, 16); 2292 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2293 if (Rn == 15) 2294 return false; 2295 break; 2296 case eEncodingA1: 2297 Rn = Bits32(opcode, 19, 16); 2298 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2299 break; 2300 default: 2301 return false; 2302 } 2303 // Read the register value from the operand register Rn. 2304 uint32_t reg_val = ReadCoreReg(Rn, &success); 2305 if (!success) 2306 return false; 2307 2308 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2309 2310 EmulateInstruction::Context context; 2311 context.type = EmulateInstruction::eContextImmediate; 2312 context.SetNoArgs (); 2313 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2314 return false; 2315 2316 return true; 2317} 2318 2319// Compare Negative (register) adds a register value and an optionally-shifted register value. 2320// It updates the condition flags based on the result, and discards the result. 2321bool 2322EmulateInstructionARM::EmulateCMNReg (ARMEncoding encoding) 2323{ 2324#if 0 2325 // ARM pseudo code... 2326 if ConditionPassed() then 2327 EncodingSpecificOperations(); 2328 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2329 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2330 APSR.N = result<31>; 2331 APSR.Z = IsZeroBit(result); 2332 APSR.C = carry; 2333 APSR.V = overflow; 2334#endif 2335 2336 bool success = false; 2337 const uint32_t opcode = OpcodeAsUnsigned (&success); 2338 if (!success) 2339 return false; 2340 2341 uint32_t Rn; // the first operand 2342 uint32_t Rm; // the second operand 2343 ARM_ShifterType shift_t; 2344 uint32_t shift_n; // the shift applied to the value read from Rm 2345 switch (encoding) { 2346 case eEncodingT1: 2347 Rn = Bits32(opcode, 2, 0); 2348 Rm = Bits32(opcode, 5, 3); 2349 shift_t = SRType_LSL; 2350 shift_n = 0; 2351 break; 2352 case eEncodingT2: 2353 Rn = Bits32(opcode, 19, 16); 2354 Rm = Bits32(opcode, 3, 0); 2355 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2356 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2357 if (Rn == 15 || BadReg(Rm)) 2358 return false; 2359 break; 2360 case eEncodingA1: 2361 Rn = Bits32(opcode, 19, 16); 2362 Rm = Bits32(opcode, 3, 0); 2363 shift_n = DecodeImmShiftARM(opcode, shift_t); 2364 break; 2365 default: 2366 return false; 2367 } 2368 // Read the register value from register Rn. 2369 uint32_t val1 = ReadCoreReg(Rn, &success); 2370 if (!success) 2371 return false; 2372 2373 // Read the register value from register Rm. 2374 uint32_t val2 = ReadCoreReg(Rm, &success); 2375 if (!success) 2376 return false; 2377 2378 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 2379 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2380 2381 EmulateInstruction::Context context; 2382 context.type = EmulateInstruction::eContextImmediate; 2383 context.SetNoArgs(); 2384 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2385 return false; 2386 2387 return true; 2388} 2389 2390// Compare (immediate) subtracts an immediate value from a register value. 2391// It updates the condition flags based on the result, and discards the result. 2392bool 2393EmulateInstructionARM::EmulateCMPImm (ARMEncoding encoding) 2394{ 2395#if 0 2396 // ARM pseudo code... 2397 if ConditionPassed() then 2398 EncodingSpecificOperations(); 2399 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2400 APSR.N = result<31>; 2401 APSR.Z = IsZeroBit(result); 2402 APSR.C = carry; 2403 APSR.V = overflow; 2404#endif 2405 2406 bool success = false; 2407 const uint32_t opcode = OpcodeAsUnsigned (&success); 2408 if (!success) 2409 return false; 2410 2411 uint32_t Rn; // the first operand 2412 uint32_t imm32; // the immediate value to be compared with 2413 switch (encoding) { 2414 case eEncodingT1: 2415 Rn = Bits32(opcode, 10, 8); 2416 imm32 = Bits32(opcode, 7, 0); 2417 break; 2418 case eEncodingT2: 2419 Rn = Bits32(opcode, 19, 16); 2420 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2421 if (Rn == 15) 2422 return false; 2423 break; 2424 case eEncodingA1: 2425 Rn = Bits32(opcode, 19, 16); 2426 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2427 break; 2428 default: 2429 return false; 2430 } 2431 // Read the register value from the operand register Rn. 2432 uint32_t reg_val = ReadCoreReg(Rn, &success); 2433 if (!success) 2434 return false; 2435 2436 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2437 2438 EmulateInstruction::Context context; 2439 context.type = EmulateInstruction::eContextImmediate; 2440 context.SetNoArgs (); 2441 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2442 return false; 2443 2444 return true; 2445} 2446 2447// Compare (register) subtracts an optionally-shifted register value from a register value. 2448// It updates the condition flags based on the result, and discards the result. 2449bool 2450EmulateInstructionARM::EmulateCMPReg (ARMEncoding encoding) 2451{ 2452#if 0 2453 // ARM pseudo code... 2454 if ConditionPassed() then 2455 EncodingSpecificOperations(); 2456 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2457 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2458 APSR.N = result<31>; 2459 APSR.Z = IsZeroBit(result); 2460 APSR.C = carry; 2461 APSR.V = overflow; 2462#endif 2463 2464 bool success = false; 2465 const uint32_t opcode = OpcodeAsUnsigned (&success); 2466 if (!success) 2467 return false; 2468 2469 uint32_t Rn; // the first operand 2470 uint32_t Rm; // the second operand 2471 ARM_ShifterType shift_t; 2472 uint32_t shift_n; // the shift applied to the value read from Rm 2473 switch (encoding) { 2474 case eEncodingT1: 2475 Rn = Bits32(opcode, 2, 0); 2476 Rm = Bits32(opcode, 5, 3); 2477 shift_t = SRType_LSL; 2478 shift_n = 0; 2479 break; 2480 case eEncodingT2: 2481 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2482 Rm = Bits32(opcode, 6, 3); 2483 shift_t = SRType_LSL; 2484 shift_n = 0; 2485 if (Rn < 8 && Rm < 8) 2486 return false; 2487 if (Rn == 15 || Rm == 15) 2488 return false; 2489 break; 2490 case eEncodingA1: 2491 Rn = Bits32(opcode, 19, 16); 2492 Rm = Bits32(opcode, 3, 0); 2493 shift_n = DecodeImmShiftARM(opcode, shift_t); 2494 break; 2495 default: 2496 return false; 2497 } 2498 // Read the register value from register Rn. 2499 uint32_t val1 = ReadCoreReg(Rn, &success); 2500 if (!success) 2501 return false; 2502 2503 // Read the register value from register Rm. 2504 uint32_t val2 = ReadCoreReg(Rm, &success); 2505 if (!success) 2506 return false; 2507 2508 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 2509 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2510 2511 EmulateInstruction::Context context; 2512 context.type = EmulateInstruction::eContextImmediate; 2513 context.SetNoArgs(); 2514 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2515 return false; 2516 2517 return true; 2518} 2519 2520// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2521// shifting in copies of its sign bit, and writes the result to the destination register. It can 2522// optionally update the condition flags based on the result. 2523bool 2524EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding) 2525{ 2526#if 0 2527 // ARM pseudo code... 2528 if ConditionPassed() then 2529 EncodingSpecificOperations(); 2530 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2531 if d == 15 then // Can only occur for ARM encoding 2532 ALUWritePC(result); // setflags is always FALSE here 2533 else 2534 R[d] = result; 2535 if setflags then 2536 APSR.N = result<31>; 2537 APSR.Z = IsZeroBit(result); 2538 APSR.C = carry; 2539 // APSR.V unchanged 2540#endif 2541 2542 return EmulateShiftImm(encoding, SRType_ASR); 2543} 2544 2545// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2546// shifting in copies of its sign bit, and writes the result to the destination register. 2547// The variable number of bits is read from the bottom byte of a register. It can optionally update 2548// the condition flags based on the result. 2549bool 2550EmulateInstructionARM::EmulateASRReg (ARMEncoding encoding) 2551{ 2552#if 0 2553 // ARM pseudo code... 2554 if ConditionPassed() then 2555 EncodingSpecificOperations(); 2556 shift_n = UInt(R[m]<7:0>); 2557 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2558 R[d] = result; 2559 if setflags then 2560 APSR.N = result<31>; 2561 APSR.Z = IsZeroBit(result); 2562 APSR.C = carry; 2563 // APSR.V unchanged 2564#endif 2565 2566 return EmulateShiftReg(encoding, SRType_ASR); 2567} 2568 2569// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2570// shifting in zeros, and writes the result to the destination register. It can optionally 2571// update the condition flags based on the result. 2572bool 2573EmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding) 2574{ 2575#if 0 2576 // ARM pseudo code... 2577 if ConditionPassed() then 2578 EncodingSpecificOperations(); 2579 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2580 if d == 15 then // Can only occur for ARM encoding 2581 ALUWritePC(result); // setflags is always FALSE here 2582 else 2583 R[d] = result; 2584 if setflags then 2585 APSR.N = result<31>; 2586 APSR.Z = IsZeroBit(result); 2587 APSR.C = carry; 2588 // APSR.V unchanged 2589#endif 2590 2591 return EmulateShiftImm(encoding, SRType_LSL); 2592} 2593 2594// Logical Shift Left (register) shifts a register value left by a variable number of bits, 2595// shifting in zeros, and writes the result to the destination register. The variable number 2596// of bits is read from the bottom byte of a register. It can optionally update the condition 2597// flags based on the result. 2598bool 2599EmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding) 2600{ 2601#if 0 2602 // ARM pseudo code... 2603 if ConditionPassed() then 2604 EncodingSpecificOperations(); 2605 shift_n = UInt(R[m]<7:0>); 2606 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2607 R[d] = result; 2608 if setflags then 2609 APSR.N = result<31>; 2610 APSR.Z = IsZeroBit(result); 2611 APSR.C = carry; 2612 // APSR.V unchanged 2613#endif 2614 2615 return EmulateShiftReg(encoding, SRType_LSL); 2616} 2617 2618// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 2619// shifting in zeros, and writes the result to the destination register. It can optionally 2620// update the condition flags based on the result. 2621bool 2622EmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding) 2623{ 2624#if 0 2625 // ARM pseudo code... 2626 if ConditionPassed() then 2627 EncodingSpecificOperations(); 2628 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 2629 if d == 15 then // Can only occur for ARM encoding 2630 ALUWritePC(result); // setflags is always FALSE here 2631 else 2632 R[d] = result; 2633 if setflags then 2634 APSR.N = result<31>; 2635 APSR.Z = IsZeroBit(result); 2636 APSR.C = carry; 2637 // APSR.V unchanged 2638#endif 2639 2640 return EmulateShiftImm(encoding, SRType_LSR); 2641} 2642 2643// Logical Shift Right (register) shifts a register value right by a variable number of bits, 2644// shifting in zeros, and writes the result to the destination register. The variable number 2645// of bits is read from the bottom byte of a register. It can optionally update the condition 2646// flags based on the result. 2647bool 2648EmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding) 2649{ 2650#if 0 2651 // ARM pseudo code... 2652 if ConditionPassed() then 2653 EncodingSpecificOperations(); 2654 shift_n = UInt(R[m]<7:0>); 2655 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 2656 R[d] = result; 2657 if setflags then 2658 APSR.N = result<31>; 2659 APSR.Z = IsZeroBit(result); 2660 APSR.C = carry; 2661 // APSR.V unchanged 2662#endif 2663 2664 return EmulateShiftReg(encoding, SRType_LSR); 2665} 2666 2667// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 2668// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2669// It can optionally update the condition flags based on the result. 2670bool 2671EmulateInstructionARM::EmulateRORImm (ARMEncoding encoding) 2672{ 2673#if 0 2674 // ARM pseudo code... 2675 if ConditionPassed() then 2676 EncodingSpecificOperations(); 2677 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2678 if d == 15 then // Can only occur for ARM encoding 2679 ALUWritePC(result); // setflags is always FALSE here 2680 else 2681 R[d] = result; 2682 if setflags then 2683 APSR.N = result<31>; 2684 APSR.Z = IsZeroBit(result); 2685 APSR.C = carry; 2686 // APSR.V unchanged 2687#endif 2688 2689 return EmulateShiftImm(encoding, SRType_ROR); 2690} 2691 2692// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 2693// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 2694// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 2695// flags based on the result. 2696bool 2697EmulateInstructionARM::EmulateRORReg (ARMEncoding encoding) 2698{ 2699#if 0 2700 // ARM pseudo code... 2701 if ConditionPassed() then 2702 EncodingSpecificOperations(); 2703 shift_n = UInt(R[m]<7:0>); 2704 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 2705 R[d] = result; 2706 if setflags then 2707 APSR.N = result<31>; 2708 APSR.Z = IsZeroBit(result); 2709 APSR.C = carry; 2710 // APSR.V unchanged 2711#endif 2712 2713 return EmulateShiftReg(encoding, SRType_ROR); 2714} 2715 2716// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 2717// with the carry flag shifted into bit [31]. 2718// 2719// RRX can optionally update the condition flags based on the result. 2720// In that case, bit [0] is shifted into the carry flag. 2721bool 2722EmulateInstructionARM::EmulateRRX (ARMEncoding encoding) 2723{ 2724#if 0 2725 // ARM pseudo code... 2726 if ConditionPassed() then 2727 EncodingSpecificOperations(); 2728 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 2729 if d == 15 then // Can only occur for ARM encoding 2730 ALUWritePC(result); // setflags is always FALSE here 2731 else 2732 R[d] = result; 2733 if setflags then 2734 APSR.N = result<31>; 2735 APSR.Z = IsZeroBit(result); 2736 APSR.C = carry; 2737 // APSR.V unchanged 2738#endif 2739 2740 return EmulateShiftImm(encoding, SRType_RRX); 2741} 2742 2743bool 2744EmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type) 2745{ 2746 assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 2747 2748 bool success = false; 2749 const uint32_t opcode = OpcodeAsUnsigned (&success); 2750 if (!success) 2751 return false; 2752 2753 if (ConditionPassed()) 2754 { 2755 uint32_t Rd; // the destination register 2756 uint32_t Rm; // the first operand register 2757 uint32_t imm5; // encoding for the shift amount 2758 uint32_t carry; // the carry bit after the shift operation 2759 bool setflags; 2760 2761 // Special case handling! 2762 // A8.6.139 ROR (immediate) -- Encoding T1 2763 if (shift_type == SRType_ROR && encoding == eEncodingT1) 2764 { 2765 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 2766 // have the same decoding of bit fields as the other Thumb2 shift operations. 2767 encoding = eEncodingT2; 2768 } 2769 2770 switch (encoding) { 2771 case eEncodingT1: 2772 // Due to the above special case handling! 2773 assert(shift_type != SRType_ROR); 2774 2775 Rd = Bits32(opcode, 2, 0); 2776 Rm = Bits32(opcode, 5, 3); 2777 setflags = !InITBlock(); 2778 imm5 = Bits32(opcode, 10, 6); 2779 break; 2780 case eEncodingT2: 2781 // A8.6.141 RRX 2782 assert(shift_type != SRType_RRX); 2783 2784 Rd = Bits32(opcode, 11, 8); 2785 Rm = Bits32(opcode, 3, 0); 2786 setflags = BitIsSet(opcode, 20); 2787 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 2788 if (BadReg(Rd) || BadReg(Rm)) 2789 return false; 2790 break; 2791 case eEncodingA1: 2792 Rd = Bits32(opcode, 15, 12); 2793 Rm = Bits32(opcode, 3, 0); 2794 setflags = BitIsSet(opcode, 20); 2795 imm5 = Bits32(opcode, 11, 7); 2796 break; 2797 default: 2798 return false; 2799 } 2800 2801 // A8.6.139 ROR (immediate) 2802 if (shift_type == SRType_ROR && imm5 == 0) 2803 shift_type = SRType_RRX; 2804 2805 // Get the first operand. 2806 uint32_t value = ReadCoreReg (Rm, &success); 2807 if (!success) 2808 return false; 2809 2810 // Decode the shift amount if not RRX. 2811 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 2812 2813 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 2814 2815 // The context specifies that an immediate is to be moved into Rd. 2816 EmulateInstruction::Context context; 2817 context.type = EmulateInstruction::eContextImmediate; 2818 context.SetNoArgs (); 2819 2820 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2821 return false; 2822 } 2823 return true; 2824} 2825 2826bool 2827EmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type) 2828{ 2829 assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR); 2830 2831 bool success = false; 2832 const uint32_t opcode = OpcodeAsUnsigned (&success); 2833 if (!success) 2834 return false; 2835 2836 if (ConditionPassed()) 2837 { 2838 uint32_t Rd; // the destination register 2839 uint32_t Rn; // the first operand register 2840 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 2841 uint32_t carry; // the carry bit after the shift operation 2842 bool setflags; 2843 switch (encoding) { 2844 case eEncodingT1: 2845 Rd = Bits32(opcode, 2, 0); 2846 Rn = Rd; 2847 Rm = Bits32(opcode, 5, 3); 2848 setflags = !InITBlock(); 2849 break; 2850 case eEncodingT2: 2851 Rd = Bits32(opcode, 11, 8); 2852 Rn = Bits32(opcode, 19, 16); 2853 Rm = Bits32(opcode, 3, 0); 2854 setflags = BitIsSet(opcode, 20); 2855 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 2856 return false; 2857 break; 2858 case eEncodingA1: 2859 Rd = Bits32(opcode, 15, 12); 2860 Rn = Bits32(opcode, 3, 0); 2861 Rm = Bits32(opcode, 11, 8); 2862 setflags = BitIsSet(opcode, 20); 2863 if (Rd == 15 || Rn == 15 || Rm == 15) 2864 return false; 2865 break; 2866 default: 2867 return false; 2868 } 2869 2870 // Get the first operand. 2871 uint32_t value = ReadCoreReg (Rn, &success); 2872 if (!success) 2873 return false; 2874 // Get the Rm register content. 2875 uint32_t val = ReadCoreReg (Rm, &success); 2876 if (!success) 2877 return false; 2878 2879 // Get the shift amount. 2880 uint32_t amt = Bits32(val, 7, 0); 2881 2882 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); 2883 2884 // The context specifies that an immediate is to be moved into Rd. 2885 EmulateInstruction::Context context; 2886 context.type = EmulateInstruction::eContextImmediate; 2887 context.SetNoArgs (); 2888 2889 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2890 return false; 2891 } 2892 return true; 2893} 2894 2895// LDM loads multiple registers from consecutive memory locations, using an 2896// address from a base register. Optionally the address just above the highest of those locations 2897// can be written back to the base register. 2898bool 2899EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 2900{ 2901#if 0 2902 // ARM pseudo code... 2903 if ConditionPassed() 2904 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 2905 address = R[n]; 2906 2907 for i = 0 to 14 2908 if registers<i> == '1' then 2909 R[i] = MemA[address, 4]; address = address + 4; 2910 if registers<15> == '1' then 2911 LoadWritePC (MemA[address, 4]); 2912 2913 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 2914 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2915 2916#endif 2917 2918 bool success = false; 2919 const uint32_t opcode = OpcodeAsUnsigned (&success); 2920 if (!success) 2921 return false; 2922 2923 if (ConditionPassed()) 2924 { 2925 uint32_t n; 2926 uint32_t registers = 0; 2927 bool wback; 2928 const uint32_t addr_byte_size = GetAddressByteSize(); 2929 switch (encoding) 2930 { 2931 case eEncodingT1: 2932 // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’); 2933 n = Bits32 (opcode, 10, 8); 2934 registers = Bits32 (opcode, 7, 0); 2935 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2936 wback = BitIsClear (registers, n); 2937 // if BitCount(registers) < 1 then UNPREDICTABLE; 2938 if (BitCount(registers) < 1) 2939 return false; 2940 break; 2941 case eEncodingT2: 2942 // if W == ’1’ && Rn == ’1101’ then SEE POP; 2943 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2944 n = Bits32 (opcode, 19, 16); 2945 registers = Bits32 (opcode, 15, 0); 2946 registers = registers & 0xdfff; // Make sure bit 13 is zero. 2947 wback = BitIsSet (opcode, 21); 2948 2949 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2950 if ((n == 15) 2951 || (BitCount (registers) < 2) 2952 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2953 return false; 2954 2955 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2956 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2957 return false; 2958 2959 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2960 if (wback 2961 && BitIsSet (registers, n)) 2962 return false; 2963 break; 2964 2965 case eEncodingA1: 2966 n = Bits32 (opcode, 19, 16); 2967 registers = Bits32 (opcode, 15, 0); 2968 wback = BitIsSet (opcode, 21); 2969 if ((n == 15) 2970 || (BitCount (registers) < 1)) 2971 return false; 2972 break; 2973 default: 2974 return false; 2975 } 2976 2977 int32_t offset = 0; 2978 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2979 if (!success) 2980 return false; 2981 2982 EmulateInstruction::Context context; 2983 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2984 Register dwarf_reg; 2985 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2986 context.SetRegisterPlusOffset (dwarf_reg, offset); 2987 2988 for (int i = 0; i < 14; ++i) 2989 { 2990 if (BitIsSet (registers, i)) 2991 { 2992 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2993 context.SetRegisterPlusOffset (dwarf_reg, offset); 2994 if (wback && (n == 13)) // Pop Instruction 2995 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2996 2997 // R[i] = MemA [address, 4]; address = address + 4; 2998 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 2999 if (!success) 3000 return false; 3001 3002 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3003 return false; 3004 3005 offset += addr_byte_size; 3006 } 3007 } 3008 3009 if (BitIsSet (registers, 15)) 3010 { 3011 //LoadWritePC (MemA [address, 4]); 3012 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3013 context.SetRegisterPlusOffset (dwarf_reg, offset); 3014 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3015 if (!success) 3016 return false; 3017 // In ARMv5T and above, this is an interworking branch. 3018 if (!LoadWritePC(context, data)) 3019 return false; 3020 } 3021 3022 if (wback && BitIsClear (registers, n)) 3023 { 3024 // R[n] = R[n] + 4 * BitCount (registers) 3025 int32_t offset = addr_byte_size * BitCount (registers); 3026 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3027 context.SetRegisterPlusOffset (dwarf_reg, offset); 3028 3029 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3030 return false; 3031 } 3032 if (wback && BitIsSet (registers, n)) 3033 // R[n] bits(32) UNKNOWN; 3034 return WriteBits32Unknown (n); 3035 } 3036 return true; 3037} 3038 3039// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers. 3040// The consecutive memorty locations end at this address and the address just below the lowest of those locations 3041// can optionally be written back tot he base registers. 3042bool 3043EmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding) 3044{ 3045#if 0 3046 // ARM pseudo code... 3047 if ConditionPassed() then 3048 EncodingSpecificOperations(); 3049 address = R[n] - 4*BitCount(registers) + 4; 3050 3051 for i = 0 to 14 3052 if registers<i> == ’1’ then 3053 R[i] = MemA[address,4]; address = address + 4; 3054 3055 if registers<15> == ’1’ then 3056 LoadWritePC(MemA[address,4]); 3057 3058 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 3059 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 3060#endif 3061 3062 bool success = false; 3063 const uint32_t opcode = OpcodeAsUnsigned (&success); 3064 if (!success) 3065 return false; 3066 3067 if (ConditionPassed()) 3068 { 3069 uint32_t n; 3070 uint32_t registers = 0; 3071 bool wback; 3072 const uint32_t addr_byte_size = GetAddressByteSize(); 3073 3074 // EncodingSpecificOperations(); 3075 switch (encoding) 3076 { 3077 case eEncodingA1: 3078 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3079 n = Bits32 (opcode, 19, 16); 3080 registers = Bits32 (opcode, 15, 0); 3081 wback = BitIsSet (opcode, 21); 3082 3083 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3084 if ((n == 15) || (BitCount (registers) < 1)) 3085 return false; 3086 3087 break; 3088 3089 default: 3090 return false; 3091 } 3092 // address = R[n] - 4*BitCount(registers) + 4; 3093 3094 int32_t offset = 0; 3095 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3096 3097 if (!success) 3098 return false; 3099 3100 address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3101 3102 EmulateInstruction::Context context; 3103 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3104 Register dwarf_reg; 3105 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3106 context.SetRegisterPlusOffset (dwarf_reg, offset); 3107 3108 // for i = 0 to 14 3109 for (int i = 0; i < 14; ++i) 3110 { 3111 // if registers<i> == ’1’ then 3112 if (BitIsSet (registers, i)) 3113 { 3114 // R[i] = MemA[address,4]; address = address + 4; 3115 context.SetRegisterPlusOffset (dwarf_reg, offset); 3116 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3117 if (!success) 3118 return false; 3119 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3120 return false; 3121 offset += addr_byte_size; 3122 } 3123 } 3124 3125 // if registers<15> == ’1’ then 3126 // LoadWritePC(MemA[address,4]); 3127 if (BitIsSet (registers, 15)) 3128 { 3129 context.SetRegisterPlusOffset (dwarf_reg, offset); 3130 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3131 if (!success) 3132 return false; 3133 // In ARMv5T and above, this is an interworking branch. 3134 if (!LoadWritePC(context, data)) 3135 return false; 3136 } 3137 3138 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 3139 if (wback && BitIsClear (registers, n)) 3140 { 3141 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3142 if (!success) 3143 return false; 3144 3145 offset = (addr_byte_size * BitCount (registers)) * -1; 3146 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3147 context.SetImmediateSigned (offset); 3148 addr = addr + offset; 3149 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3150 return false; 3151 } 3152 3153 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 3154 if (wback && BitIsSet (registers, n)) 3155 return WriteBits32Unknown (n); 3156 } 3157 return true; 3158} 3159 3160// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3161// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3162// be optionally written back to the base register. 3163bool 3164EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 3165{ 3166#if 0 3167 // ARM pseudo code... 3168 if ConditionPassed() then 3169 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3170 address = R[n] - 4*BitCount(registers); 3171 3172 for i = 0 to 14 3173 if registers<i> == ’1’ then 3174 R[i] = MemA[address,4]; address = address + 4; 3175 if registers<15> == ’1’ then 3176 LoadWritePC(MemA[address,4]); 3177 3178 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 3179 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3180#endif 3181 3182 bool success = false; 3183 const uint32_t opcode = OpcodeAsUnsigned (&success); 3184 if (!success) 3185 return false; 3186 3187 if (ConditionPassed()) 3188 { 3189 uint32_t n; 3190 uint32_t registers = 0; 3191 bool wback; 3192 const uint32_t addr_byte_size = GetAddressByteSize(); 3193 switch (encoding) 3194 { 3195 case eEncodingT1: 3196 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 3197 n = Bits32 (opcode, 19, 16); 3198 registers = Bits32 (opcode, 15, 0); 3199 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3200 wback = BitIsSet (opcode, 21); 3201 3202 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 3203 if ((n == 15) 3204 || (BitCount (registers) < 2) 3205 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3206 return false; 3207 3208 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3209 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3210 return false; 3211 3212 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3213 if (wback && BitIsSet (registers, n)) 3214 return false; 3215 3216 break; 3217 3218 case eEncodingA1: 3219 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3220 n = Bits32 (opcode, 19, 16); 3221 registers = Bits32 (opcode, 15, 0); 3222 wback = BitIsSet (opcode, 21); 3223 3224 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3225 if ((n == 15) || (BitCount (registers) < 1)) 3226 return false; 3227 3228 break; 3229 3230 default: 3231 return false; 3232 } 3233 3234 // address = R[n] - 4*BitCount(registers); 3235 3236 int32_t offset = 0; 3237 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3238 3239 if (!success) 3240 return false; 3241 3242 address = address - (addr_byte_size * BitCount (registers)); 3243 EmulateInstruction::Context context; 3244 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3245 Register dwarf_reg; 3246 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3247 context.SetRegisterPlusOffset (dwarf_reg, offset); 3248 3249 for (int i = 0; i < 14; ++i) 3250 { 3251 if (BitIsSet (registers, i)) 3252 { 3253 // R[i] = MemA[address,4]; address = address + 4; 3254 context.SetRegisterPlusOffset (dwarf_reg, offset); 3255 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3256 if (!success) 3257 return false; 3258 3259 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3260 return false; 3261 3262 offset += addr_byte_size; 3263 } 3264 } 3265 3266 // if registers<15> == ’1’ then 3267 // LoadWritePC(MemA[address,4]); 3268 if (BitIsSet (registers, 15)) 3269 { 3270 context.SetRegisterPlusOffset (dwarf_reg, offset); 3271 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3272 if (!success) 3273 return false; 3274 // In ARMv5T and above, this is an interworking branch. 3275 if (!LoadWritePC(context, data)) 3276 return false; 3277 } 3278 3279 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 3280 if (wback && BitIsClear (registers, n)) 3281 { 3282 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3283 if (!success) 3284 return false; 3285 3286 offset = (addr_byte_size * BitCount (registers)) * -1; 3287 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3288 context.SetImmediateSigned (offset); 3289 addr = addr + offset; 3290 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3291 return false; 3292 } 3293 3294 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3295 if (wback && BitIsSet (registers, n)) 3296 return WriteBits32Unknown (n); 3297 } 3298 return true; 3299} 3300 3301// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3302// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3303// optinoally be written back to the base register. 3304bool 3305EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 3306{ 3307#if 0 3308 if ConditionPassed() then 3309 EncodingSpecificOperations(); 3310 address = R[n] + 4; 3311 3312 for i = 0 to 14 3313 if registers<i> == ’1’ then 3314 R[i] = MemA[address,4]; address = address + 4; 3315 if registers<15> == ’1’ then 3316 LoadWritePC(MemA[address,4]); 3317 3318 if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 3319 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 3320#endif 3321 3322 bool success = false; 3323 const uint32_t opcode = OpcodeAsUnsigned (&success); 3324 if (!success) 3325 return false; 3326 3327 if (ConditionPassed()) 3328 { 3329 uint32_t n; 3330 uint32_t registers = 0; 3331 bool wback; 3332 const uint32_t addr_byte_size = GetAddressByteSize(); 3333 switch (encoding) 3334 { 3335 case eEncodingA1: 3336 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3337 n = Bits32 (opcode, 19, 16); 3338 registers = Bits32 (opcode, 15, 0); 3339 wback = BitIsSet (opcode, 21); 3340 3341 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3342 if ((n == 15) || (BitCount (registers) < 1)) 3343 return false; 3344 3345 break; 3346 default: 3347 return false; 3348 } 3349 // address = R[n] + 4; 3350 3351 int32_t offset = 0; 3352 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3353 3354 if (!success) 3355 return false; 3356 3357 address = address + addr_byte_size; 3358 3359 EmulateInstruction::Context context; 3360 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3361 Register dwarf_reg; 3362 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3363 context.SetRegisterPlusOffset (dwarf_reg, offset); 3364 3365 for (int i = 0; i < 14; ++i) 3366 { 3367 if (BitIsSet (registers, i)) 3368 { 3369 // R[i] = MemA[address,4]; address = address + 4; 3370 3371 context.SetRegisterPlusOffset (dwarf_reg, offset); 3372 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3373 if (!success) 3374 return false; 3375 3376 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3377 return false; 3378 3379 offset += addr_byte_size; 3380 } 3381 } 3382 3383 // if registers<15> == ’1’ then 3384 // LoadWritePC(MemA[address,4]); 3385 if (BitIsSet (registers, 15)) 3386 { 3387 context.SetRegisterPlusOffset (dwarf_reg, offset); 3388 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3389 if (!success) 3390 return false; 3391 // In ARMv5T and above, this is an interworking branch. 3392 if (!LoadWritePC(context, data)) 3393 return false; 3394 } 3395 3396 // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 3397 if (wback && BitIsClear (registers, n)) 3398 { 3399 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3400 if (!success) 3401 return false; 3402 3403 offset = addr_byte_size * BitCount (registers); 3404 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3405 context.SetImmediateSigned (offset); 3406 addr = addr + offset; 3407 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3408 return false; 3409 } 3410 3411 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3412 if (wback && BitIsSet (registers, n)) 3413 return WriteBits32Unknown (n); 3414 } 3415 return true; 3416} 3417 3418// Load Register (immediate) calculates an address from a base register value and 3419// an immediate offset, loads a word from memory, and writes to a register. 3420// LDR (immediate, Thumb) 3421bool 3422EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 3423{ 3424#if 0 3425 // ARM pseudo code... 3426 if (ConditionPassed()) 3427 { 3428 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3429 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3430 address = if index then offset_addr else R[n]; 3431 data = MemU[address,4]; 3432 if wback then R[n] = offset_addr; 3433 if t == 15 then 3434 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3435 elsif UnalignedSupport() || address<1:0> = '00' then 3436 R[t] = data; 3437 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3438 } 3439#endif 3440 3441 bool success = false; 3442 const uint32_t opcode = OpcodeAsUnsigned (&success); 3443 if (!success) 3444 return false; 3445 3446 if (ConditionPassed()) 3447 { 3448 uint32_t Rt; // the destination register 3449 uint32_t Rn; // the base register 3450 uint32_t imm32; // the immediate offset used to form the address 3451 addr_t offset_addr; // the offset address 3452 addr_t address; // the calculated address 3453 uint32_t data; // the literal data value from memory load 3454 bool add, index, wback; 3455 switch (encoding) { 3456 case eEncodingT1: 3457 Rt = Bits32(opcode, 5, 3); 3458 Rn = Bits32(opcode, 2, 0); 3459 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3460 // index = TRUE; add = TRUE; wback = FALSE 3461 add = true; 3462 index = true; 3463 wback = false; 3464 break; 3465 default: 3466 return false; 3467 } 3468 uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 3469 if (!success) 3470 return false; 3471 if (add) 3472 offset_addr = base + imm32; 3473 else 3474 offset_addr = base - imm32; 3475 3476 address = (index ? offset_addr : base); 3477 3478 if (wback) 3479 { 3480 EmulateInstruction::Context ctx; 3481 ctx.type = EmulateInstruction::eContextRegisterPlusOffset; 3482 Register dwarf_reg; 3483 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 3484 ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base)); 3485 3486 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3487 return false; 3488 } 3489 3490 // Prepare to write to the Rt register. 3491 EmulateInstruction::Context context; 3492 context.type = EmulateInstruction::eContextImmediate; 3493 context.SetNoArgs (); 3494 3495 // Read memory from the address. 3496 data = MemURead(context, address, 4, 0, &success); 3497 if (!success) 3498 return false; 3499 3500 if (Rt == 15) 3501 { 3502 if (Bits32(address, 1, 0) == 0) 3503 { 3504 if (!LoadWritePC(context, data)) 3505 return false; 3506 } 3507 else 3508 return false; 3509 } 3510 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3511 { 3512 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3513 return false; 3514 } 3515 else 3516 return false; 3517 } 3518 return true; 3519} 3520 3521// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3522// from a base register. The consecutive memory locations start at this address, and teh address just above the last 3523// of those locations can optionally be written back to the base register. 3524bool 3525EmulateInstructionARM::EmulateSTM (ARMEncoding encoding) 3526{ 3527#if 0 3528 if ConditionPassed() then 3529 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3530 address = R[n]; 3531 3532 for i = 0 to 14 3533 if registers<i> == ’1’ then 3534 if i == n && wback && i != LowestSetBit(registers) then 3535 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3536 else 3537 MemA[address,4] = R[i]; 3538 address = address + 4; 3539 3540 if registers<15> == ’1’ then // Only possible for encoding A1 3541 MemA[address,4] = PCStoreValue(); 3542 if wback then R[n] = R[n] + 4*BitCount(registers); 3543#endif 3544 3545 bool success = false; 3546 const uint32_t opcode = OpcodeAsUnsigned (&success); 3547 if (!success) 3548 return false; 3549 3550 if (ConditionPassed ()) 3551 { 3552 uint32_t n; 3553 uint32_t registers = 0; 3554 bool wback; 3555 const uint32_t addr_byte_size = GetAddressByteSize(); 3556 3557 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3558 switch (encoding) 3559 { 3560 case eEncodingT1: 3561 // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE; 3562 n = Bits32 (opcode, 10, 8); 3563 registers = Bits32 (opcode, 7, 0); 3564 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3565 wback = true; 3566 3567 // if BitCount(registers) < 1 then UNPREDICTABLE; 3568 if (BitCount (registers) < 1) 3569 return false; 3570 3571 break; 3572 3573 case eEncodingT2: 3574 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3575 n = Bits32 (opcode, 19, 16); 3576 registers = Bits32 (opcode, 15, 0); 3577 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3578 wback = BitIsSet (opcode, 21); 3579 3580 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3581 if ((n == 15) || (BitCount (registers) < 2)) 3582 return false; 3583 3584 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3585 if (wback && BitIsSet (registers, n)) 3586 return false; 3587 3588 break; 3589 3590 case eEncodingA1: 3591 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3592 n = Bits32 (opcode, 19, 16); 3593 registers = Bits32 (opcode, 15, 0); 3594 wback = BitIsSet (opcode, 21); 3595 3596 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3597 if ((n == 15) || (BitCount (registers) < 1)) 3598 return false; 3599 3600 break; 3601 3602 default: 3603 return false; 3604 } 3605 3606 // address = R[n]; 3607 int32_t offset = 0; 3608 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3609 if (!success) 3610 return false; 3611 3612 EmulateInstruction::Context context; 3613 context.type = EmulateInstruction::eContextRegisterStore; 3614 Register base_reg; 3615 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3616 3617 // for i = 0 to 14 3618 for (int i = 0; i < 14; ++i) 3619 { 3620 int lowest_set_bit = 14; 3621 // if registers<i> == ’1’ then 3622 if (BitIsSet (registers, i)) 3623 { 3624 if (i < lowest_set_bit) 3625 lowest_set_bit = i; 3626 // if i == n && wback && i != LowestSetBit(registers) then 3627 if ((i == n) && wback && (i != lowest_set_bit)) 3628 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3629 WriteBits32UnknownToMemory (address + offset); 3630 else 3631 { 3632 // MemA[address,4] = R[i]; 3633 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3634 if (!success) 3635 return false; 3636 3637 Register data_reg; 3638 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3639 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3640 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3641 return false; 3642 } 3643 3644 // address = address + 4; 3645 offset += addr_byte_size; 3646 } 3647 } 3648 3649 // if registers<15> == ’1’ then // Only possible for encoding A1 3650 // MemA[address,4] = PCStoreValue(); 3651 if (BitIsSet (registers, 15)) 3652 { 3653 Register pc_reg; 3654 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3655 context.SetRegisterPlusOffset (pc_reg, 8); 3656 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3657 if (!success) 3658 return false; 3659 3660 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3661 return false; 3662 } 3663 3664 // if wback then R[n] = R[n] + 4*BitCount(registers); 3665 if (wback) 3666 { 3667 offset = addr_byte_size * BitCount (registers); 3668 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3669 context.SetImmediateSigned (offset); 3670 addr_t data = address + offset; 3671 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3672 return false; 3673 } 3674 } 3675 return true; 3676} 3677 3678// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 3679// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3680// of those locations can optionally be written back to the base register. 3681bool 3682EmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding) 3683{ 3684#if 0 3685 if ConditionPassed() then 3686 EncodingSpecificOperations(); 3687 address = R[n] - 4*BitCount(registers) + 4; 3688 3689 for i = 0 to 14 3690 if registers<i> == ’1’ then 3691 if i == n && wback && i != LowestSetBit(registers) then 3692 MemA[address,4] = bits(32) UNKNOWN; 3693 else 3694 MemA[address,4] = R[i]; 3695 address = address + 4; 3696 3697 if registers<15> == ’1’ then 3698 MemA[address,4] = PCStoreValue(); 3699 3700 if wback then R[n] = R[n] - 4*BitCount(registers); 3701#endif 3702 3703 bool success = false; 3704 const uint32_t opcode = OpcodeAsUnsigned (&success); 3705 if (!success) 3706 return false; 3707 3708 if (ConditionPassed ()) 3709 { 3710 uint32_t n; 3711 uint32_t registers = 0; 3712 bool wback; 3713 const uint32_t addr_byte_size = GetAddressByteSize(); 3714 3715 // EncodingSpecificOperations(); 3716 switch (encoding) 3717 { 3718 case eEncodingA1: 3719 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3720 n = Bits32 (opcode, 19, 16); 3721 registers = Bits32 (opcode, 15, 0); 3722 wback = BitIsSet (opcode, 21); 3723 3724 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3725 if ((n == 15) || (BitCount (registers) < 1)) 3726 return false; 3727 break; 3728 default: 3729 return false; 3730 } 3731 3732 // address = R[n] - 4*BitCount(registers) + 4; 3733 int32_t offset = 0; 3734 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3735 if (!success) 3736 return false; 3737 3738 address = address - (addr_byte_size * BitCount (registers)) + 4; 3739 3740 EmulateInstruction::Context context; 3741 context.type = EmulateInstruction::eContextRegisterStore; 3742 Register base_reg; 3743 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3744 3745 // for i = 0 to 14 3746 for (int i = 0; i < 14; ++i) 3747 { 3748 int lowest_bit_set = 14; 3749 // if registers<i> == ’1’ then 3750 if (BitIsSet (registers, i)) 3751 { 3752 if (i < lowest_bit_set) 3753 lowest_bit_set = i; 3754 //if i == n && wback && i != LowestSetBit(registers) then 3755 if ((i == n) && wback && (i != lowest_bit_set)) 3756 // MemA[address,4] = bits(32) UNKNOWN; 3757 WriteBits32UnknownToMemory (address + offset); 3758 else 3759 { 3760 // MemA[address,4] = R[i]; 3761 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3762 if (!success) 3763 return false; 3764 3765 Register data_reg; 3766 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3767 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3768 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3769 return false; 3770 } 3771 3772 // address = address + 4; 3773 offset += addr_byte_size; 3774 } 3775 } 3776 3777 // if registers<15> == ’1’ then 3778 // MemA[address,4] = PCStoreValue(); 3779 if (BitIsSet (registers, 15)) 3780 { 3781 Register pc_reg; 3782 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3783 context.SetRegisterPlusOffset (pc_reg, 8); 3784 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3785 if (!success) 3786 return false; 3787 3788 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3789 return false; 3790 } 3791 3792 // if wback then R[n] = R[n] - 4*BitCount(registers); 3793 if (wback) 3794 { 3795 offset = (addr_byte_size * BitCount (registers)) * -1; 3796 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3797 context.SetImmediateSigned (offset); 3798 addr_t data = address + offset; 3799 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3800 return false; 3801 } 3802 } 3803 return true; 3804} 3805 3806// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 3807// from a base register. The consecutive memory locations end just below this address, and the address of the first of 3808// those locations can optionally be written back to the base register. 3809bool 3810EmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding) 3811{ 3812#if 0 3813 if ConditionPassed() then 3814 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3815 address = R[n] - 4*BitCount(registers); 3816 3817 for i = 0 to 14 3818 if registers<i> == ’1’ then 3819 if i == n && wback && i != LowestSetBit(registers) then 3820 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3821 else 3822 MemA[address,4] = R[i]; 3823 address = address + 4; 3824 3825 if registers<15> == ’1’ then // Only possible for encoding A1 3826 MemA[address,4] = PCStoreValue(); 3827 3828 if wback then R[n] = R[n] - 4*BitCount(registers); 3829#endif 3830 3831 3832 bool success = false; 3833 const uint32_t opcode = OpcodeAsUnsigned (&success); 3834 if (!success) 3835 return false; 3836 3837 if (ConditionPassed ()) 3838 { 3839 uint32_t n; 3840 uint32_t registers = 0; 3841 bool wback; 3842 const uint32_t addr_byte_size = GetAddressByteSize(); 3843 3844 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3845 switch (encoding) 3846 { 3847 case eEncodingT1: 3848 // if W == ’1’ && Rn == ’1101’ then SEE PUSH; 3849 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 3850 { 3851 // See PUSH 3852 } 3853 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3854 n = Bits32 (opcode, 19, 16); 3855 registers = Bits32 (opcode, 15, 0); 3856 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3857 wback = BitIsSet (opcode, 21); 3858 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3859 if ((n == 15) || BitCount (registers) < 2) 3860 return false; 3861 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3862 if (wback && BitIsSet (registers, n)) 3863 return false; 3864 break; 3865 3866 case eEncodingA1: 3867 // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH; 3868 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 3869 { 3870 // See Push 3871 } 3872 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3873 n = Bits32 (opcode, 19, 16); 3874 registers = Bits32 (opcode, 15, 0); 3875 wback = BitIsSet (opcode, 21); 3876 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3877 if ((n == 15) || BitCount (registers) < 1) 3878 return false; 3879 break; 3880 3881 default: 3882 return false; 3883 } 3884 3885 // address = R[n] - 4*BitCount(registers); 3886 3887 int32_t offset = 0; 3888 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3889 if (!success) 3890 return false; 3891 3892 address = address - (addr_byte_size * BitCount (registers)); 3893 3894 EmulateInstruction::Context context; 3895 context.type = EmulateInstruction::eContextRegisterStore; 3896 Register base_reg; 3897 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3898 3899 // for i = 0 to 14 3900 for (int i = 0; i < 14; ++i) 3901 { 3902 uint32_t lowest_set_bit = 14; 3903 // if registers<i> == ’1’ then 3904 if (BitIsSet (registers, i)) 3905 { 3906 if (i < lowest_set_bit) 3907 lowest_set_bit = i; 3908 // if i == n && wback && i != LowestSetBit(registers) then 3909 if ((i == n) && wback && (i != lowest_set_bit)) 3910 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3911 WriteBits32UnknownToMemory (address + offset); 3912 else 3913 { 3914 // MemA[address,4] = R[i]; 3915 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3916 if (!success) 3917 return false; 3918 3919 Register data_reg; 3920 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3921 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3922 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 3923 return false; 3924 } 3925 3926 // address = address + 4; 3927 offset += addr_byte_size; 3928 } 3929 } 3930 3931 // if registers<15> == ’1’ then // Only possible for encoding A1 3932 // MemA[address,4] = PCStoreValue(); 3933 if (BitIsSet (registers, 15)) 3934 { 3935 Register pc_reg; 3936 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3937 context.SetRegisterPlusOffset (pc_reg, 8); 3938 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3939 if (!success) 3940 return false; 3941 3942 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 3943 return false; 3944 } 3945 3946 // if wback then R[n] = R[n] - 4*BitCount(registers); 3947 if (wback) 3948 { 3949 offset = (addr_byte_size * BitCount (registers)) * -1; 3950 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3951 context.SetImmediateSigned (offset); 3952 addr_t data = address + offset; 3953 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3954 return false; 3955 } 3956 } 3957 return true; 3958} 3959 3960// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 3961// from a base register. The consecutive memory locations start just above this address, and the address of the last 3962// of those locations can optionally be written back to the base register. 3963bool 3964EmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding) 3965{ 3966#if 0 3967 if ConditionPassed() then 3968 EncodingSpecificOperations(); 3969 address = R[n] + 4; 3970 3971 for i = 0 to 14 3972 if registers<i> == ’1’ then 3973 if i == n && wback && i != LowestSetBit(registers) then 3974 MemA[address,4] = bits(32) UNKNOWN; 3975 else 3976 MemA[address,4] = R[i]; 3977 address = address + 4; 3978 3979 if registers<15> == ’1’ then 3980 MemA[address,4] = PCStoreValue(); 3981 3982 if wback then R[n] = R[n] + 4*BitCount(registers); 3983#endif 3984 3985 bool success = false; 3986 const uint32_t opcode = OpcodeAsUnsigned (&success); 3987 if (!success) 3988 return false; 3989 3990 if (ConditionPassed()) 3991 { 3992 uint32_t n; 3993 uint32_t registers = 0; 3994 bool wback; 3995 const uint32_t addr_byte_size = GetAddressByteSize(); 3996 3997 // EncodingSpecificOperations(); 3998 switch (encoding) 3999 { 4000 case eEncodingA1: 4001 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 4002 n = Bits32 (opcode, 19, 16); 4003 registers = Bits32 (opcode, 15, 0); 4004 wback = BitIsSet (opcode, 21); 4005 4006 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4007 if ((n == 15) && (BitCount (registers) < 1)) 4008 return false; 4009 break; 4010 default: 4011 return false; 4012 } 4013 // address = R[n] + 4; 4014 4015 int32_t offset = 0; 4016 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4017 if (!success) 4018 return false; 4019 4020 address = address + addr_byte_size; 4021 4022 EmulateInstruction::Context context; 4023 context.type = EmulateInstruction::eContextRegisterStore; 4024 Register base_reg; 4025 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4026 4027 uint32_t lowest_set_bit = 14; 4028 // for i = 0 to 14 4029 for (int i = 0; i < 14; ++i) 4030 { 4031 // if registers<i> == ’1’ then 4032 if (BitIsSet (registers, i)) 4033 { 4034 if (i < lowest_set_bit) 4035 lowest_set_bit = i; 4036 // if i == n && wback && i != LowestSetBit(registers) then 4037 if ((i == n) && wback && (i != lowest_set_bit)) 4038 // MemA[address,4] = bits(32) UNKNOWN; 4039 WriteBits32UnknownToMemory (address + offset); 4040 // else 4041 else 4042 { 4043 // MemA[address,4] = R[i]; 4044 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4045 if (!success) 4046 return false; 4047 4048 Register data_reg; 4049 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 4050 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4051 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4052 return false; 4053 } 4054 4055 // address = address + 4; 4056 offset += addr_byte_size; 4057 } 4058 } 4059 4060 // if registers<15> == ’1’ then 4061 // MemA[address,4] = PCStoreValue(); 4062 if (BitIsSet (registers, 15)) 4063 { 4064 Register pc_reg; 4065 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 4066 context.SetRegisterPlusOffset (pc_reg, 8); 4067 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 4068 if (!success) 4069 return false; 4070 4071 if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size)) 4072 return false; 4073 } 4074 4075 // if wback then R[n] = R[n] + 4*BitCount(registers); 4076 if (wback) 4077 { 4078 offset = addr_byte_size * BitCount (registers); 4079 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4080 context.SetImmediateSigned (offset); 4081 addr_t data = address + offset; 4082 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4083 return false; 4084 } 4085 } 4086 return true; 4087} 4088 4089// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4090// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4091bool 4092EmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding) 4093{ 4094#if 0 4095 if ConditionPassed() then 4096 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4097 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4098 address = if index then offset_addr else R[n]; 4099 if UnalignedSupport() || address<1:0> == ’00’ then 4100 MemU[address,4] = R[t]; 4101 else // Can only occur before ARMv7 4102 MemU[address,4] = bits(32) UNKNOWN; 4103 if wback then R[n] = offset_addr; 4104#endif 4105 4106 bool success = false; 4107 const uint32_t opcode = OpcodeAsUnsigned (&success); 4108 if (!success) 4109 return false; 4110 4111 if (ConditionPassed()) 4112 { 4113 const uint32_t addr_byte_size = GetAddressByteSize(); 4114 4115 uint32_t t; 4116 uint32_t n; 4117 uint32_t imm32; 4118 bool index; 4119 bool add; 4120 bool wback; 4121 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4122 switch (encoding) 4123 { 4124 case eEncodingT1: 4125 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32); 4126 t = Bits32 (opcode, 2, 0); 4127 n = Bits32 (opcode, 5, 3); 4128 imm32 = Bits32 (opcode, 10, 6) << 2; 4129 4130 // index = TRUE; add = TRUE; wback = FALSE; 4131 index = true; 4132 add = false; 4133 wback = false; 4134 break; 4135 4136 case eEncodingT2: 4137 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32); 4138 t = Bits32 (opcode, 10, 8); 4139 n = 13; 4140 imm32 = Bits32 (opcode, 7, 0) << 2; 4141 4142 // index = TRUE; add = TRUE; wback = FALSE; 4143 index = true; 4144 add = true; 4145 wback = false; 4146 break; 4147 4148 case eEncodingT3: 4149 // if Rn == ’1111’ then UNDEFINED; 4150 if (Bits32 (opcode, 19, 16) == 15) 4151 return false; 4152 4153 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4154 t = Bits32 (opcode, 15, 12); 4155 n = Bits32 (opcode, 19, 16); 4156 imm32 = Bits32 (opcode, 11, 0); 4157 4158 // index = TRUE; add = TRUE; wback = FALSE; 4159 index = true; 4160 add = true; 4161 wback = false; 4162 4163 // if t == 15 then UNPREDICTABLE; 4164 if (t == 15) 4165 return false; 4166 break; 4167 4168 case eEncodingT4: 4169 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT; 4170 // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH; 4171 // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 4172 if ((Bits32 (opcode, 19, 16) == 15) 4173 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4174 return false; 4175 4176 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4177 t = Bits32 (opcode, 15, 12); 4178 n = Bits32 (opcode, 19, 16); 4179 imm32 = Bits32 (opcode, 7, 0); 4180 4181 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 4182 index = BitIsSet (opcode, 10); 4183 add = BitIsSet (opcode, 9); 4184 wback = BitIsSet (opcode, 8); 4185 4186 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4187 if ((t == 15) || (wback && (n == t))) 4188 return false; 4189 break; 4190 4191 default: 4192 return false; 4193 } 4194 4195 addr_t offset_addr; 4196 addr_t address; 4197 4198 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4199 uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4200 if (!success) 4201 return false; 4202 4203 if (add) 4204 offset_addr = base_address + imm32; 4205 else 4206 offset_addr = base_address - imm32; 4207 4208 // address = if index then offset_addr else R[n]; 4209 if (index) 4210 address = offset_addr; 4211 else 4212 address = base_address; 4213 4214 EmulateInstruction::Context context; 4215 context.type = eContextRegisterStore; 4216 Register base_reg; 4217 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4218 4219 // if UnalignedSupport() || address<1:0> == ’00’ then 4220 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4221 { 4222 // MemU[address,4] = R[t]; 4223 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4224 if (!success) 4225 return false; 4226 4227 Register data_reg; 4228 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 4229 int32_t offset = address - base_address; 4230 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4231 if (!MemUWrite (context, address, data, addr_byte_size)) 4232 return false; 4233 } 4234 else 4235 { 4236 // MemU[address,4] = bits(32) UNKNOWN; 4237 WriteBits32UnknownToMemory (address); 4238 } 4239 4240 // if wback then R[n] = offset_addr; 4241 if (wback) 4242 { 4243 context.type = eContextRegisterLoad; 4244 context.SetAddress (offset_addr); 4245 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4246 return false; 4247 } 4248 } 4249 return true; 4250} 4251 4252// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4253// word from a register to memory. The offset register value can optionally be shifted. 4254bool 4255EmulateInstructionARM::EmulateSTRRegister (ARMEncoding encoding) 4256{ 4257#if 0 4258 if ConditionPassed() then 4259 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4260 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4261 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4262 address = if index then offset_addr else R[n]; 4263 if t == 15 then // Only possible for encoding A1 4264 data = PCStoreValue(); 4265 else 4266 data = R[t]; 4267 if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then 4268 MemU[address,4] = data; 4269 else // Can only occur before ARMv7 4270 MemU[address,4] = bits(32) UNKNOWN; 4271 if wback then R[n] = offset_addr; 4272#endif 4273 4274 bool success = false; 4275 const uint32_t opcode = OpcodeAsUnsigned (&success); 4276 if (!success) 4277 return false; 4278 4279 if (ConditionPassed()) 4280 { 4281 const uint32_t addr_byte_size = GetAddressByteSize(); 4282 4283 uint32_t t; 4284 uint32_t n; 4285 uint32_t m; 4286 ARM_ShifterType shift_t; 4287 uint32_t shift_n; 4288 bool index; 4289 bool add; 4290 bool wback; 4291 4292 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4293 switch (encoding) 4294 { 4295 case eEncodingT1: 4296 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4297 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4298 t = Bits32 (opcode, 2, 0); 4299 n = Bits32 (opcode, 5, 3); 4300 m = Bits32 (opcode, 8, 6); 4301 4302 // index = TRUE; add = TRUE; wback = FALSE; 4303 index = true; 4304 add = true; 4305 wback = false; 4306 4307 // (shift_t, shift_n) = (SRType_LSL, 0); 4308 shift_t = SRType_LSL; 4309 shift_n = 0; 4310 break; 4311 4312 case eEncodingT2: 4313 // if Rn == ’1111’ then UNDEFINED; 4314 if (Bits32 (opcode, 19, 16) == 15) 4315 return false; 4316 4317 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4318 t = Bits32 (opcode, 15, 12); 4319 n = Bits32 (opcode, 19, 16); 4320 m = Bits32 (opcode, 3, 0); 4321 4322 // index = TRUE; add = TRUE; wback = FALSE; 4323 index = true; 4324 add = true; 4325 wback = false; 4326 4327 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4328 shift_t = SRType_LSL; 4329 shift_n = Bits32 (opcode, 5, 4); 4330 4331 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4332 if ((t == 15) || (BadReg (m))) 4333 return false; 4334 break; 4335 4336 case eEncodingA1: 4337 { 4338 // if P == ’0’ && W == ’1’ then SEE STRT; 4339 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4340 t = Bits32 (opcode, 15, 12); 4341 n = Bits32 (opcode, 19, 16); 4342 m = Bits32 (opcode, 3, 0); 4343 4344 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 4345 index = BitIsSet (opcode, 24); 4346 add = BitIsSet (opcode, 23); 4347 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4348 4349 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4350 uint32_t typ = Bits32 (opcode, 6, 5); 4351 uint32_t imm5 = Bits32 (opcode, 11, 7); 4352 shift_n = DecodeImmShift(typ, imm5, shift_t); 4353 4354 // if m == 15 then UNPREDICTABLE; 4355 if (m == 15) 4356 return false; 4357 4358 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4359 if (wback && ((n == 15) || (n == t))) 4360 return false; 4361 4362 break; 4363 } 4364 default: 4365 return false; 4366 } 4367 4368 addr_t offset_addr; 4369 addr_t address; 4370 int32_t offset = 0; 4371 4372 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4373 if (!success) 4374 return false; 4375 4376 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4377 if (!success) 4378 return false; 4379 4380 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4381 offset = Shift (Rm_data, shift_t, shift_n, APSR_C); 4382 4383 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4384 if (add) 4385 offset_addr = base_address + offset; 4386 else 4387 offset_addr = base_address - offset; 4388 4389 // address = if index then offset_addr else R[n]; 4390 if (index) 4391 address = offset_addr; 4392 else 4393 address = base_address; 4394 4395 uint32_t data; 4396 // if t == 15 then // Only possible for encoding A1 4397 if (t == 15) 4398 // data = PCStoreValue(); 4399 data = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 4400 else 4401 // data = R[t]; 4402 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4403 4404 if (!success) 4405 return false; 4406 4407 EmulateInstruction::Context context; 4408 context.type = eContextRegisterStore; 4409 4410 // if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then 4411 if (UnalignedSupport () 4412 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4413 || CurrentInstrSet() == eModeARM) 4414 { 4415 // MemU[address,4] = data; 4416 4417 Register base_reg; 4418 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4419 4420 Register data_reg; 4421 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 4422 4423 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4424 if (!MemUWrite (context, address, data, addr_byte_size)) 4425 return false; 4426 4427 } 4428 else 4429 // MemU[address,4] = bits(32) UNKNOWN; 4430 WriteBits32UnknownToMemory (address); 4431 4432 // if wback then R[n] = offset_addr; 4433 if (wback) 4434 { 4435 context.type = eContextRegisterLoad; 4436 context.SetAddress (offset_addr); 4437 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4438 return false; 4439 } 4440 4441 } 4442 return true; 4443} 4444 4445bool 4446EmulateInstructionARM::EmulateSTRBThumb (ARMEncoding encoding) 4447{ 4448#if 0 4449 if ConditionPassed() then 4450 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4451 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4452 address = if index then offset_addr else R[n]; 4453 MemU[address,1] = R[t]<7:0>; 4454 if wback then R[n] = offset_addr; 4455#endif 4456 4457 4458 bool success = false; 4459 const uint32_t opcode = OpcodeAsUnsigned (&success); 4460 if (!success) 4461 return false; 4462 4463 if (ConditionPassed ()) 4464 { 4465 uint32_t t; 4466 uint32_t n; 4467 uint32_t imm32; 4468 bool index; 4469 bool add; 4470 bool wback; 4471 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4472 switch (encoding) 4473 { 4474 case eEncodingT1: 4475 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4476 t = Bits32 (opcode, 2, 0); 4477 n = Bits32 (opcode, 5, 3); 4478 imm32 = Bits32 (opcode, 10, 6); 4479 4480 // index = TRUE; add = TRUE; wback = FALSE; 4481 index = true; 4482 add = true; 4483 wback = false; 4484 break; 4485 4486 case eEncodingT2: 4487 // if Rn == ’1111’ then UNDEFINED; 4488 if (Bits32 (opcode, 19, 16) == 15) 4489 return false; 4490 4491 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4492 t = Bits32 (opcode, 15, 12); 4493 n = Bits32 (opcode, 19, 16); 4494 imm32 = Bits32 (opcode, 11, 0); 4495 4496 // index = TRUE; add = TRUE; wback = FALSE; 4497 index = true; 4498 add = true; 4499 wback = false; 4500 4501 // if BadReg(t) then UNPREDICTABLE; 4502 if (BadReg (t)) 4503 return false; 4504 break; 4505 4506 case eEncodingT3: 4507 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRBT; 4508 // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 4509 if (Bits32 (opcode, 19, 16) == 15) 4510 return false; 4511 4512 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4513 t = Bits32 (opcode, 15, 12); 4514 n = Bits32 (opcode, 19, 16); 4515 imm32 = Bits32 (opcode, 7, 0); 4516 4517 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 4518 index = BitIsSet (opcode, 10); 4519 add = BitIsSet (opcode, 9); 4520 wback = BitIsSet (opcode, 8); 4521 4522 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4523 if ((BadReg (t)) || (wback && (n == t))) 4524 return false; 4525 break; 4526 4527 default: 4528 return false; 4529 } 4530 4531 addr_t offset_addr; 4532 addr_t address; 4533 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4534 if (!success) 4535 return false; 4536 4537 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4538 if (add) 4539 offset_addr = base_address + imm32; 4540 else 4541 offset_addr = base_address - imm32; 4542 4543 // address = if index then offset_addr else R[n]; 4544 if (index) 4545 address = offset_addr; 4546 else 4547 address = base_address; 4548 4549 // MemU[address,1] = R[t]<7:0> 4550 Register base_reg; 4551 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 4552 4553 Register data_reg; 4554 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 4555 4556 EmulateInstruction::Context context; 4557 context.type = eContextRegisterStore; 4558 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4559 4560 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4561 if (!success) 4562 return false; 4563 4564 data = Bits32 (data, 7, 0); 4565 4566 if (!MemUWrite (context, address, data, 1)) 4567 return false; 4568 4569 // if wback then R[n] = offset_addr; 4570 if (wback) 4571 { 4572 context.type = eContextRegisterLoad; 4573 context.SetAddress (offset_addr); 4574 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4575 return false; 4576 } 4577 4578 } 4579 4580 return true; 4581} 4582 4583// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 4584// and writes the result to the destination register. It can optionally update the condition flags 4585// based on the result. 4586bool 4587EmulateInstructionARM::EmulateADCImm (ARMEncoding encoding) 4588{ 4589#if 0 4590 // ARM pseudo code... 4591 if ConditionPassed() then 4592 EncodingSpecificOperations(); 4593 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 4594 if d == 15 then // Can only occur for ARM encoding 4595 ALUWritePC(result); // setflags is always FALSE here 4596 else 4597 R[d] = result; 4598 if setflags then 4599 APSR.N = result<31>; 4600 APSR.Z = IsZeroBit(result); 4601 APSR.C = carry; 4602 APSR.V = overflow; 4603#endif 4604 4605 bool success = false; 4606 const uint32_t opcode = OpcodeAsUnsigned (&success); 4607 if (!success) 4608 return false; 4609 4610 if (ConditionPassed()) 4611 { 4612 uint32_t Rd, Rn; 4613 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 4614 bool setflags; 4615 switch (encoding) 4616 { 4617 case eEncodingT1: 4618 Rd = Bits32(opcode, 11, 8); 4619 Rn = Bits32(opcode, 19, 16); 4620 setflags = BitIsSet(opcode, 20); 4621 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 4622 if (BadReg(Rd) || BadReg(Rn)) 4623 return false; 4624 break; 4625 case eEncodingA1: 4626 Rd = Bits32(opcode, 15, 12); 4627 Rn = Bits32(opcode, 19, 16); 4628 setflags = BitIsSet(opcode, 20); 4629 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 4630 // TODO: Emulate SUBS PC, LR and related instructions. 4631 if (Rd == 15 && setflags) 4632 return false; 4633 break; 4634 default: 4635 return false; 4636 } 4637 4638 // Read the first operand. 4639 int32_t val1 = ReadCoreReg(Rn, &success); 4640 if (!success) 4641 return false; 4642 4643 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 4644 4645 EmulateInstruction::Context context; 4646 context.type = EmulateInstruction::eContextImmediate; 4647 context.SetNoArgs (); 4648 4649 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 4650 return false; 4651 } 4652 return true; 4653} 4654 4655// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 4656// register value, and writes the result to the destination register. It can optionally update the 4657// condition flags based on the result. 4658bool 4659EmulateInstructionARM::EmulateADCReg (ARMEncoding encoding) 4660{ 4661#if 0 4662 // ARM pseudo code... 4663 if ConditionPassed() then 4664 EncodingSpecificOperations(); 4665 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 4666 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 4667 if d == 15 then // Can only occur for ARM encoding 4668 ALUWritePC(result); // setflags is always FALSE here 4669 else 4670 R[d] = result; 4671 if setflags then 4672 APSR.N = result<31>; 4673 APSR.Z = IsZeroBit(result); 4674 APSR.C = carry; 4675 APSR.V = overflow; 4676#endif 4677 4678 bool success = false; 4679 const uint32_t opcode = OpcodeAsUnsigned (&success); 4680 if (!success) 4681 return false; 4682 4683 if (ConditionPassed()) 4684 { 4685 uint32_t Rd, Rn, Rm; 4686 ARM_ShifterType shift_t; 4687 uint32_t shift_n; // the shift applied to the value read from Rm 4688 bool setflags; 4689 switch (encoding) 4690 { 4691 case eEncodingT1: 4692 Rd = Rn = Bits32(opcode, 2, 0); 4693 Rm = Bits32(opcode, 5, 3); 4694 setflags = !InITBlock(); 4695 shift_t = SRType_LSL; 4696 shift_n = 0; 4697 break; 4698 case eEncodingT2: 4699 Rd = Bits32(opcode, 11, 8); 4700 Rn = Bits32(opcode, 19, 16); 4701 Rm = Bits32(opcode, 3, 0); 4702 setflags = BitIsSet(opcode, 20); 4703 shift_n = DecodeImmShiftThumb(opcode, shift_t); 4704 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 4705 return false; 4706 break; 4707 case eEncodingA1: 4708 Rd = Bits32(opcode, 15, 12); 4709 Rn = Bits32(opcode, 19, 16); 4710 Rm = Bits32(opcode, 3, 0); 4711 setflags = BitIsSet(opcode, 20); 4712 shift_n = DecodeImmShiftARM(opcode, shift_t); 4713 // TODO: Emulate SUBS PC, LR and related instructions. 4714 if (Rd == 15 && setflags) 4715 return false; 4716 break; 4717 default: 4718 return false; 4719 } 4720 4721 // Read the first operand. 4722 int32_t val1 = ReadCoreReg(Rn, &success); 4723 if (!success) 4724 return false; 4725 4726 // Read the second operand. 4727 int32_t val2 = ReadCoreReg(Rm, &success); 4728 if (!success) 4729 return false; 4730 4731 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 4732 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 4733 4734 EmulateInstruction::Context context; 4735 context.type = EmulateInstruction::eContextImmediate; 4736 context.SetNoArgs (); 4737 4738 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 4739 return false; 4740 } 4741 return true; 4742} 4743 4744// This instruction adds an immediate value to the PC value to form a PC-relative address, 4745// and writes the result to the destination register. 4746bool 4747EmulateInstructionARM::EmulateADR (ARMEncoding encoding) 4748{ 4749#if 0 4750 // ARM pseudo code... 4751 if ConditionPassed() then 4752 EncodingSpecificOperations(); 4753 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 4754 if d == 15 then // Can only occur for ARM encodings 4755 ALUWritePC(result); 4756 else 4757 R[d] = result; 4758#endif 4759 4760 bool success = false; 4761 const uint32_t opcode = OpcodeAsUnsigned (&success); 4762 if (!success) 4763 return false; 4764 4765 if (ConditionPassed()) 4766 { 4767 uint32_t Rd; 4768 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 4769 bool add; 4770 switch (encoding) 4771 { 4772 case eEncodingT1: 4773 Rd = Bits32(opcode, 10, 8); 4774 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 4775 break; 4776 case eEncodingT2: 4777 case eEncodingT3: 4778 Rd = Bits32(opcode, 11, 8); 4779 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 4780 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 4781 if (BadReg(Rd)) 4782 return false; 4783 break; 4784 case eEncodingA1: 4785 case eEncodingA2: 4786 Rd = Bits32(opcode, 15, 12); 4787 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 4788 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 4789 break; 4790 default: 4791 return false; 4792 } 4793 4794 // Read the PC value. 4795 uint32_t pc = ReadCoreReg(PC_REG, &success); 4796 if (!success) 4797 return false; 4798 4799 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 4800 4801 EmulateInstruction::Context context; 4802 context.type = EmulateInstruction::eContextImmediate; 4803 context.SetNoArgs (); 4804 4805 if (!WriteCoreReg(context, result, Rd)) 4806 return false; 4807 } 4808 return true; 4809} 4810 4811// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 4812// to the destination register. It can optionally update the condition flags based on the result. 4813bool 4814EmulateInstructionARM::EmulateANDImm (ARMEncoding encoding) 4815{ 4816#if 0 4817 // ARM pseudo code... 4818 if ConditionPassed() then 4819 EncodingSpecificOperations(); 4820 result = R[n] AND imm32; 4821 if d == 15 then // Can only occur for ARM encoding 4822 ALUWritePC(result); // setflags is always FALSE here 4823 else 4824 R[d] = result; 4825 if setflags then 4826 APSR.N = result<31>; 4827 APSR.Z = IsZeroBit(result); 4828 APSR.C = carry; 4829 // APSR.V unchanged 4830#endif 4831 4832 bool success = false; 4833 const uint32_t opcode = OpcodeAsUnsigned (&success); 4834 if (!success) 4835 return false; 4836 4837 if (ConditionPassed()) 4838 { 4839 uint32_t Rd, Rn; 4840 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 4841 bool setflags; 4842 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 4843 switch (encoding) 4844 { 4845 case eEncodingT1: 4846 Rd = Bits32(opcode, 11, 8); 4847 Rn = Bits32(opcode, 19, 16); 4848 setflags = BitIsSet(opcode, 20); 4849 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 4850 // if Rd == '1111' && S == '1' then SEE TST (immediate); 4851 if (Rd == 15 && setflags) 4852 return EmulateTSTImm(eEncodingT1); 4853 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 4854 return false; 4855 break; 4856 case eEncodingA1: 4857 Rd = Bits32(opcode, 15, 12); 4858 Rn = Bits32(opcode, 19, 16); 4859 setflags = BitIsSet(opcode, 20); 4860 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 4861 // TODO: Emulate SUBS PC, LR and related instructions. 4862 if (Rd == 15 && setflags) 4863 return false; 4864 break; 4865 default: 4866 return false; 4867 } 4868 4869 // Read the first operand. 4870 uint32_t val1 = ReadCoreReg(Rn, &success); 4871 if (!success) 4872 return false; 4873 4874 uint32_t result = val1 & imm32; 4875 4876 EmulateInstruction::Context context; 4877 context.type = EmulateInstruction::eContextImmediate; 4878 context.SetNoArgs (); 4879 4880 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 4881 return false; 4882 } 4883 return true; 4884} 4885 4886// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 4887// and writes the result to the destination register. It can optionally update the condition flags 4888// based on the result. 4889bool 4890EmulateInstructionARM::EmulateANDReg (ARMEncoding encoding) 4891{ 4892#if 0 4893 // ARM pseudo code... 4894 if ConditionPassed() then 4895 EncodingSpecificOperations(); 4896 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 4897 result = R[n] AND shifted; 4898 if d == 15 then // Can only occur for ARM encoding 4899 ALUWritePC(result); // setflags is always FALSE here 4900 else 4901 R[d] = result; 4902 if setflags then 4903 APSR.N = result<31>; 4904 APSR.Z = IsZeroBit(result); 4905 APSR.C = carry; 4906 // APSR.V unchanged 4907#endif 4908 4909 bool success = false; 4910 const uint32_t opcode = OpcodeAsUnsigned (&success); 4911 if (!success) 4912 return false; 4913 4914 if (ConditionPassed()) 4915 { 4916 uint32_t Rd, Rn, Rm; 4917 ARM_ShifterType shift_t; 4918 uint32_t shift_n; // the shift applied to the value read from Rm 4919 bool setflags; 4920 uint32_t carry; 4921 switch (encoding) 4922 { 4923 case eEncodingT1: 4924 Rd = Rn = Bits32(opcode, 2, 0); 4925 Rm = Bits32(opcode, 5, 3); 4926 setflags = !InITBlock(); 4927 shift_t = SRType_LSL; 4928 shift_n = 0; 4929 break; 4930 case eEncodingT2: 4931 Rd = Bits32(opcode, 11, 8); 4932 Rn = Bits32(opcode, 19, 16); 4933 Rm = Bits32(opcode, 3, 0); 4934 setflags = BitIsSet(opcode, 20); 4935 shift_n = DecodeImmShiftThumb(opcode, shift_t); 4936 // if Rd == '1111' && S == '1' then SEE TST (register); 4937 if (Rd == 15 && setflags) 4938 return EmulateTSTReg(eEncodingT2); 4939 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 4940 return false; 4941 break; 4942 case eEncodingA1: 4943 Rd = Bits32(opcode, 15, 12); 4944 Rn = Bits32(opcode, 19, 16); 4945 Rm = Bits32(opcode, 3, 0); 4946 setflags = BitIsSet(opcode, 20); 4947 shift_n = DecodeImmShiftARM(opcode, shift_t); 4948 // TODO: Emulate SUBS PC, LR and related instructions. 4949 if (Rd == 15 && setflags) 4950 return false; 4951 break; 4952 default: 4953 return false; 4954 } 4955 4956 // Read the first operand. 4957 uint32_t val1 = ReadCoreReg(Rn, &success); 4958 if (!success) 4959 return false; 4960 4961 // Read the second operand. 4962 uint32_t val2 = ReadCoreReg(Rm, &success); 4963 if (!success) 4964 return false; 4965 4966 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 4967 uint32_t result = val1 & shifted; 4968 4969 EmulateInstruction::Context context; 4970 context.type = EmulateInstruction::eContextImmediate; 4971 context.SetNoArgs (); 4972 4973 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 4974 return false; 4975 } 4976 return true; 4977} 4978 4979// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 4980// immediate value, and writes the result to the destination register. It can optionally update the 4981// condition flags based on the result. 4982bool 4983EmulateInstructionARM::EmulateBICImm (ARMEncoding encoding) 4984{ 4985#if 0 4986 // ARM pseudo code... 4987 if ConditionPassed() then 4988 EncodingSpecificOperations(); 4989 result = R[n] AND NOT(imm32); 4990 if d == 15 then // Can only occur for ARM encoding 4991 ALUWritePC(result); // setflags is always FALSE here 4992 else 4993 R[d] = result; 4994 if setflags then 4995 APSR.N = result<31>; 4996 APSR.Z = IsZeroBit(result); 4997 APSR.C = carry; 4998 // APSR.V unchanged 4999#endif 5000 5001 bool success = false; 5002 const uint32_t opcode = OpcodeAsUnsigned (&success); 5003 if (!success) 5004 return false; 5005 5006 if (ConditionPassed()) 5007 { 5008 uint32_t Rd, Rn; 5009 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5010 bool setflags; 5011 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5012 switch (encoding) 5013 { 5014 case eEncodingT1: 5015 Rd = Bits32(opcode, 11, 8); 5016 Rn = Bits32(opcode, 19, 16); 5017 setflags = BitIsSet(opcode, 20); 5018 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5019 if (BadReg(Rd) || BadReg(Rn)) 5020 return false; 5021 break; 5022 case eEncodingA1: 5023 Rd = Bits32(opcode, 15, 12); 5024 Rn = Bits32(opcode, 19, 16); 5025 setflags = BitIsSet(opcode, 20); 5026 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5027 // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 5028 // TODO: Emulate SUBS PC, LR and related instructions. 5029 if (Rd == 15 && setflags) 5030 return false; 5031 break; 5032 default: 5033 return false; 5034 } 5035 5036 // Read the first operand. 5037 uint32_t val1 = ReadCoreReg(Rn, &success); 5038 if (!success) 5039 return false; 5040 5041 uint32_t result = val1 & ~imm32; 5042 5043 EmulateInstruction::Context context; 5044 context.type = EmulateInstruction::eContextImmediate; 5045 context.SetNoArgs (); 5046 5047 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5048 return false; 5049 } 5050 return true; 5051} 5052 5053// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5054// optionally-shifted register value, and writes the result to the destination register. 5055// It can optionally update the condition flags based on the result. 5056bool 5057EmulateInstructionARM::EmulateBICReg (ARMEncoding encoding) 5058{ 5059#if 0 5060 // ARM pseudo code... 5061 if ConditionPassed() then 5062 EncodingSpecificOperations(); 5063 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5064 result = R[n] AND NOT(shifted); 5065 if d == 15 then // Can only occur for ARM encoding 5066 ALUWritePC(result); // setflags is always FALSE here 5067 else 5068 R[d] = result; 5069 if setflags then 5070 APSR.N = result<31>; 5071 APSR.Z = IsZeroBit(result); 5072 APSR.C = carry; 5073 // APSR.V unchanged 5074#endif 5075 5076 bool success = false; 5077 const uint32_t opcode = OpcodeAsUnsigned (&success); 5078 if (!success) 5079 return false; 5080 5081 if (ConditionPassed()) 5082 { 5083 uint32_t Rd, Rn, Rm; 5084 ARM_ShifterType shift_t; 5085 uint32_t shift_n; // the shift applied to the value read from Rm 5086 bool setflags; 5087 uint32_t carry; 5088 switch (encoding) 5089 { 5090 case eEncodingT1: 5091 Rd = Rn = Bits32(opcode, 2, 0); 5092 Rm = Bits32(opcode, 5, 3); 5093 setflags = !InITBlock(); 5094 shift_t = SRType_LSL; 5095 shift_n = 0; 5096 break; 5097 case eEncodingT2: 5098 Rd = Bits32(opcode, 11, 8); 5099 Rn = Bits32(opcode, 19, 16); 5100 Rm = Bits32(opcode, 3, 0); 5101 setflags = BitIsSet(opcode, 20); 5102 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5103 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5104 return false; 5105 break; 5106 case eEncodingA1: 5107 Rd = Bits32(opcode, 15, 12); 5108 Rn = Bits32(opcode, 19, 16); 5109 Rm = Bits32(opcode, 3, 0); 5110 setflags = BitIsSet(opcode, 20); 5111 shift_n = DecodeImmShiftARM(opcode, shift_t); 5112 // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; 5113 // TODO: Emulate SUBS PC, LR and related instructions. 5114 if (Rd == 15 && setflags) 5115 return false; 5116 break; 5117 default: 5118 return false; 5119 } 5120 5121 // Read the first operand. 5122 uint32_t val1 = ReadCoreReg(Rn, &success); 5123 if (!success) 5124 return false; 5125 5126 // Read the second operand. 5127 uint32_t val2 = ReadCoreReg(Rm, &success); 5128 if (!success) 5129 return false; 5130 5131 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 5132 uint32_t result = val1 & ~shifted; 5133 5134 EmulateInstruction::Context context; 5135 context.type = EmulateInstruction::eContextImmediate; 5136 context.SetNoArgs (); 5137 5138 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5139 return false; 5140 } 5141 return true; 5142} 5143 5144// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5145// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5146bool 5147EmulateInstructionARM::EmulateLDRImmediateARM (ARMEncoding encoding) 5148{ 5149#if 0 5150 if ConditionPassed() then 5151 EncodingSpecificOperations(); 5152 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5153 address = if index then offset_addr else R[n]; 5154 data = MemU[address,4]; 5155 if wback then R[n] = offset_addr; 5156 if t == 15 then 5157 if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 5158 elsif UnalignedSupport() || address<1:0> = ’00’ then 5159 R[t] = data; 5160 else // Can only apply before ARMv7 5161 R[t] = ROR(data, 8*UInt(address<1:0>)); 5162#endif 5163 5164 bool success = false; 5165 const uint32_t opcode = OpcodeAsUnsigned (&success); 5166 if (!success) 5167 return false; 5168 5169 if (ConditionPassed ()) 5170 { 5171 const uint32_t addr_byte_size = GetAddressByteSize(); 5172 5173 uint32_t t; 5174 uint32_t n; 5175 uint32_t imm32; 5176 bool index; 5177 bool add; 5178 bool wback; 5179 5180 switch (encoding) 5181 { 5182 case eEncodingA1: 5183 // if Rn == ’1111’ then SEE LDR (literal); 5184 // if P == ’0’ && W == ’1’ then SEE LDRT; 5185 // if Rn == ’1101’ && P == ’0’ && U == ’1’ && W == ’0’ && imm12 == ’000000000100’ then SEE POP; 5186 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5187 t = Bits32 (opcode, 15, 12); 5188 n = Bits32 (opcode, 19, 16); 5189 imm32 = Bits32 (opcode, 11, 0); 5190 5191 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 5192 index = BitIsSet (opcode, 24); 5193 add = BitIsSet (opcode, 23); 5194 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5195 5196 // if wback && n == t then UNPREDICTABLE; 5197 if (wback && (n == t)) 5198 return false; 5199 5200 break; 5201 5202 default: 5203 return false; 5204 } 5205 5206 addr_t address; 5207 addr_t offset_addr; 5208 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5209 if (!success) 5210 return false; 5211 5212 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5213 if (add) 5214 offset_addr = base_address + imm32; 5215 else 5216 offset_addr = base_address - imm32; 5217 5218 // address = if index then offset_addr else R[n]; 5219 if (index) 5220 address = offset_addr; 5221 else 5222 address = base_address; 5223 5224 // data = MemU[address,4]; 5225 5226 Register base_reg; 5227 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5228 5229 EmulateInstruction::Context context; 5230 context.type = eContextRegisterLoad; 5231 context.SetRegisterPlusOffset (base_reg, address - base_address); 5232 5233 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5234 if (!success) 5235 return false; 5236 5237 // if wback then R[n] = offset_addr; 5238 if (wback) 5239 { 5240 context.type = eContextAdjustBaseRegister; 5241 context.SetAddress (offset_addr); 5242 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5243 return false; 5244 } 5245 5246 // if t == 15 then 5247 if (t == 15) 5248 { 5249 // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 5250 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5251 { 5252 // LoadWritePC (data); 5253 context.type = eContextRegisterLoad; 5254 context.SetRegisterPlusOffset (base_reg, address - base_address); 5255 LoadWritePC (context, data); 5256 } 5257 else 5258 return false; 5259 } 5260 // elsif UnalignedSupport() || address<1:0> = ’00’ then 5261 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5262 { 5263 // R[t] = data; 5264 context.type = eContextRegisterLoad; 5265 context.SetRegisterPlusOffset (base_reg, address - base_address); 5266 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5267 return false; 5268 } 5269 // else // Can only apply before ARMv7 5270 else 5271 { 5272 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5273 data = ROR (data, Bits32 (address, 1, 0)); 5274 context.type = eContextRegisterLoad; 5275 context.SetImmediate (data); 5276 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5277 return false; 5278 } 5279 5280 } 5281 return true; 5282} 5283 5284// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5285// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5286bool 5287EmulateInstructionARM::EmulateLDRRegister (ARMEncoding encoding) 5288{ 5289#if 0 5290 if ConditionPassed() then 5291 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5292 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5293 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5294 address = if index then offset_addr else R[n]; 5295 data = MemU[address,4]; 5296 if wback then R[n] = offset_addr; 5297 if t == 15 then 5298 if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 5299 elsif UnalignedSupport() || address<1:0> = ’00’ then 5300 R[t] = data; 5301 else // Can only apply before ARMv7 5302 if CurrentInstrSet() == InstrSet_ARM then 5303 R[t] = ROR(data, 8*UInt(address<1:0>)); 5304 else 5305 R[t] = bits(32) UNKNOWN; 5306#endif 5307 5308 bool success = false; 5309 const uint32_t opcode = OpcodeAsUnsigned (&success); 5310 if (!success) 5311 return false; 5312 5313 if (ConditionPassed ()) 5314 { 5315 const uint32_t addr_byte_size = GetAddressByteSize(); 5316 5317 uint32_t t; 5318 uint32_t n; 5319 uint32_t m; 5320 bool index; 5321 bool add; 5322 bool wback; 5323 ARM_ShifterType shift_t; 5324 uint32_t shift_n; 5325 5326 switch (encoding) 5327 { 5328 case eEncodingT1: 5329 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5330 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5331 t = Bits32 (opcode, 2, 0); 5332 n = Bits32 (opcode, 5, 3); 5333 m = Bits32 (opcode, 8, 6); 5334 5335 // index = TRUE; add = TRUE; wback = FALSE; 5336 index = true; 5337 add = true; 5338 wback = false; 5339 5340 // (shift_t, shift_n) = (SRType_LSL, 0); 5341 shift_t = SRType_LSL; 5342 shift_n = 0; 5343 5344 break; 5345 5346 case eEncodingT2: 5347 // if Rn == ’1111’ then SEE LDR (literal); 5348 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5349 t = Bits32 (opcode, 15, 12); 5350 n = Bits32 (opcode, 19, 16); 5351 m = Bits32 (opcode, 3, 0); 5352 5353 // index = TRUE; add = TRUE; wback = FALSE; 5354 index = true; 5355 add = true; 5356 wback = false; 5357 5358 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5359 shift_t = SRType_LSL; 5360 shift_n = Bits32 (opcode, 5, 4); 5361 5362 // if BadReg(m) then UNPREDICTABLE; 5363 if (BadReg (m)) 5364 return false; 5365 5366 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5367 if ((t == 15) && InITBlock() && !LastInITBlock()) 5368 return false; 5369 5370 break; 5371 5372 case eEncodingA1: 5373 { 5374 // if P == ’0’ && W == ’1’ then SEE LDRT; 5375 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5376 t = Bits32 (opcode, 15, 12); 5377 n = Bits32 (opcode, 19, 16); 5378 m = Bits32 (opcode, 3, 0); 5379 5380 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 5381 index = BitIsSet (opcode, 24); 5382 add = BitIsSet (opcode, 23); 5383 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5384 5385 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5386 uint32_t type = Bits32 (opcode, 6, 5); 5387 uint32_t imm5 = Bits32 (opcode, 11, 7); 5388 shift_n = DecodeImmShift (type, imm5, shift_t); 5389 5390 // if m == 15 then UNPREDICTABLE; 5391 if (m == 15) 5392 return false; 5393 5394 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5395 if (wback && ((n == 15) || (n == t))) 5396 return false; 5397 } 5398 break; 5399 5400 5401 default: 5402 return false; 5403 } 5404 5405 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5406 if (!success) 5407 return false; 5408 5409 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5410 if (!success) 5411 return false; 5412 5413 addr_t offset_addr; 5414 addr_t address; 5415 5416 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 5417 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_inst_cpsr, APSR_C)); 5418 5419 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5420 if (add) 5421 offset_addr = Rn + offset; 5422 else 5423 offset_addr = Rn - offset; 5424 5425 // address = if index then offset_addr else R[n]; 5426 if (index) 5427 address = offset_addr; 5428 else 5429 address = Rn; 5430 5431 // data = MemU[address,4]; 5432 Register base_reg; 5433 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5434 5435 EmulateInstruction::Context context; 5436 context.type = eContextRegisterLoad; 5437 context.SetRegisterPlusOffset (base_reg, address - Rn); 5438 5439 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5440 if (!success) 5441 return false; 5442 5443 // if wback then R[n] = offset_addr; 5444 if (wback) 5445 { 5446 context.type = eContextAdjustBaseRegister; 5447 context.SetAddress (offset_addr); 5448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5449 return false; 5450 } 5451 5452 // if t == 15 then 5453 if (t == 15) 5454 { 5455 // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE; 5456 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5457 { 5458 context.type = eContextRegisterLoad; 5459 context.SetRegisterPlusOffset (base_reg, address - Rn); 5460 LoadWritePC (context, data); 5461 } 5462 else 5463 return false; 5464 } 5465 // elsif UnalignedSupport() || address<1:0> = ’00’ then 5466 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5467 { 5468 // R[t] = data; 5469 context.type = eContextRegisterLoad; 5470 context.SetRegisterPlusOffset (base_reg, address - Rn); 5471 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5472 return false; 5473 } 5474 else // Can only apply before ARMv7 5475 { 5476 // if CurrentInstrSet() == InstrSet_ARM then 5477 if (CurrentInstrSet () == eModeARM) 5478 { 5479 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5480 data = ROR (data, Bits32 (address, 1, 0)); 5481 context.type = eContextRegisterLoad; 5482 context.SetImmediate (data); 5483 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5484 return false; 5485 } 5486 else 5487 { 5488 // R[t] = bits(32) UNKNOWN; 5489 WriteBits32Unknown (t); 5490 } 5491 } 5492 } 5493 return true; 5494} 5495 5496// LDRB (immediate, Thumb) 5497bool 5498EmulateInstructionARM::EmulateLDRBImmediate (ARMEncoding encoding) 5499{ 5500#if 0 5501 if ConditionPassed() then 5502 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5503 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5504 address = if index then offset_addr else R[n]; 5505 R[t] = ZeroExtend(MemU[address,1], 32); 5506 if wback then R[n] = offset_addr; 5507#endif 5508 5509 bool success = false; 5510 const uint32_t opcode = OpcodeAsUnsigned (&success); 5511 if (!success) 5512 return false; 5513 5514 if (ConditionPassed ()) 5515 { 5516 uint32_t t; 5517 uint32_t n; 5518 uint32_t imm32; 5519 bool index; 5520 bool add; 5521 bool wback; 5522 5523 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5524 switch (encoding) 5525 { 5526 case eEncodingT1: 5527 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5528 t = Bits32 (opcode, 2, 0); 5529 n = Bits32 (opcode, 5, 3); 5530 imm32 = Bits32 (opcode, 10, 6); 5531 5532 // index = TRUE; add = TRUE; wback = FALSE; 5533 index = true; 5534 add = true; 5535 wback= false; 5536 5537 break; 5538 5539 case eEncodingT2: 5540 // if Rt == ’1111’ then SEE PLD; 5541 // if Rn == ’1111’ then SEE LDRB (literal); 5542 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5543 t = Bits32 (opcode, 15, 12); 5544 n = Bits32 (opcode, 19, 16); 5545 imm32 = Bits32 (opcode, 11, 0); 5546 5547 // index = TRUE; add = TRUE; wback = FALSE; 5548 index = true; 5549 add = true; 5550 wback = false; 5551 5552 // if t == 13 then UNPREDICTABLE; 5553 if (t == 13) 5554 return false; 5555 5556 break; 5557 5558 case eEncodingT3: 5559 // if Rt == ’1111’ && P == ’1’ && U == ’0’ && W == ’0’ then SEE PLD; 5560 // if Rn == ’1111’ then SEE LDRB (literal); 5561 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE LDRBT; 5562 // if P == ’0’ && W == ’0’ then UNDEFINED; 5563 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 5564 return false; 5565 5566 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5567 t = Bits32 (opcode, 15, 12); 5568 n = Bits32 (opcode, 19, 16); 5569 imm32 = Bits32 (opcode, 7, 0); 5570 5571 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 5572 index = BitIsSet (opcode, 10); 5573 add = BitIsSet (opcode, 9); 5574 wback = BitIsSet (opcode, 8); 5575 5576 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 5577 if (BadReg (t) || (wback && (n == t))) 5578 return false; 5579 5580 break; 5581 5582 default: 5583 return false; 5584 } 5585 5586 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5587 if (!success) 5588 return false; 5589 5590 addr_t address; 5591 addr_t offset_addr; 5592 5593 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5594 if (add) 5595 offset_addr = Rn + imm32; 5596 else 5597 offset_addr = Rn - imm32; 5598 5599 // address = if index then offset_addr else R[n]; 5600 if (index) 5601 address = offset_addr; 5602 else 5603 address = Rn; 5604 5605 // R[t] = ZeroExtend(MemU[address,1], 32); 5606 Register base_reg; 5607 Register data_reg; 5608 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5609 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 5610 5611 EmulateInstruction::Context context; 5612 context.type = eContextRegisterLoad; 5613 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 5614 5615 uint64_t data = MemURead (context, address, 1, 0, &success); 5616 if (!success) 5617 return false; 5618 5619 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5620 return false; 5621 5622 // if wback then R[n] = offset_addr; 5623 if (wback) 5624 { 5625 context.type = eContextAdjustBaseRegister; 5626 context.SetAddress (offset_addr); 5627 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5628 return false; 5629 } 5630 } 5631 return true; 5632} 5633 5634// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 5635// zero-extends it to form a 32-bit word and writes it to a register. 5636bool 5637EmulateInstructionARM::EmulateLDRBLiteral (ARMEncoding encoding) 5638{ 5639#if 0 5640 if ConditionPassed() then 5641 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 5642 base = Align(PC,4); 5643 address = if add then (base + imm32) else (base - imm32); 5644 R[t] = ZeroExtend(MemU[address,1], 32); 5645#endif 5646 5647 bool success = false; 5648 const uint32_t opcode = OpcodeAsUnsigned (&success); 5649 if (!success) 5650 return false; 5651 5652 if (ConditionPassed ()) 5653 { 5654 uint32_t t; 5655 uint32_t imm32; 5656 bool add; 5657 switch (encoding) 5658 { 5659 case eEncodingT1: 5660 // if Rt == ’1111’ then SEE PLD; 5661 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’); 5662 t = Bits32 (opcode, 15, 12); 5663 imm32 = Bits32 (opcode, 11, 0); 5664 add = BitIsSet (opcode, 23); 5665 5666 // if t == 13 then UNPREDICTABLE; 5667 if (t == 13) 5668 return false; 5669 5670 break; 5671 5672 case eEncodingA1: 5673 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’); 5674 t = Bits32 (opcode, 15, 12); 5675 imm32 = Bits32 (opcode, 11, 0); 5676 add = BitIsSet (opcode, 23); 5677 5678 // if t == 15 then UNPREDICTABLE; 5679 if (t == 15) 5680 return false; 5681 break; 5682 5683 default: 5684 return false; 5685 } 5686 5687 // base = Align(PC,4); 5688 uint32_t pc_val = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 5689 if (!success) 5690 return false; 5691 5692 uint32_t base = AlignPC (pc_val); 5693 5694 addr_t address; 5695 // address = if add then (base + imm32) else (base - imm32); 5696 if (add) 5697 address = base + imm32; 5698 else 5699 address = base - imm32; 5700 5701 // R[t] = ZeroExtend(MemU[address,1], 32); 5702 EmulateInstruction::Context context; 5703 context.type = eContextRelativeBranchImmediate; 5704 context.SetImmediate (address - base); 5705 5706 uint64_t data = MemURead (context, address, 1, 0, &success); 5707 if (!success) 5708 return false; 5709 5710 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5711 return false; 5712 } 5713 return true; 5714} 5715 5716// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 5717// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 5718// optionally be shifted. 5719bool 5720EmulateInstructionARM::EmulateLDRBRegister (ARMEncoding encoding) 5721{ 5722#if 0 5723 if ConditionPassed() then 5724 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5725 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5726 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5727 address = if index then offset_addr else R[n]; 5728 R[t] = ZeroExtend(MemU[address,1],32); 5729 if wback then R[n] = offset_addr; 5730#endif 5731 5732 bool success = false; 5733 const uint32_t opcode = OpcodeAsUnsigned (&success); 5734 if (!success) 5735 return false; 5736 5737 if (ConditionPassed ()) 5738 { 5739 uint32_t t; 5740 uint32_t n; 5741 uint32_t m; 5742 bool index; 5743 bool add; 5744 bool wback; 5745 ARM_ShifterType shift_t; 5746 uint32_t shift_n; 5747 5748 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5749 switch (encoding) 5750 { 5751 case eEncodingT1: 5752 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5753 t = Bits32 (opcode, 2, 0); 5754 n = Bits32 (opcode, 5, 3); 5755 m = Bits32 (opcode, 8, 6); 5756 5757 // index = TRUE; add = TRUE; wback = FALSE; 5758 index = true; 5759 add = true; 5760 wback = false; 5761 5762 // (shift_t, shift_n) = (SRType_LSL, 0); 5763 shift_t = SRType_LSL; 5764 shift_n = 0; 5765 break; 5766 5767 case eEncodingT2: 5768 // if Rt == ’1111’ then SEE PLD; 5769 // if Rn == ’1111’ then SEE LDRB (literal); 5770 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5771 t = Bits32 (opcode, 15, 12); 5772 n = Bits32 (opcode, 19, 16); 5773 m = Bits32 (opcode, 3, 0); 5774 5775 // index = TRUE; add = TRUE; wback = FALSE; 5776 index = true; 5777 add = true; 5778 wback = false; 5779 5780 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5781 shift_t = SRType_LSL; 5782 shift_n = Bits32 (opcode, 5, 4); 5783 5784 // if t == 13 || BadReg(m) then UNPREDICTABLE; 5785 if ((t == 13) || BadReg (m)) 5786 return false; 5787 break; 5788 5789 case eEncodingA1: 5790 { 5791 // if P == ’0’ && W == ’1’ then SEE LDRBT; 5792 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5793 t = Bits32 (opcode, 15, 12); 5794 n = Bits32 (opcode, 19, 16); 5795 m = Bits32 (opcode, 3, 0); 5796 5797 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 5798 index = BitIsSet (opcode, 24); 5799 add = BitIsSet (opcode, 23); 5800 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5801 5802 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5803 uint32_t type = Bits32 (opcode, 6, 5); 5804 uint32_t imm5 = Bits32 (opcode, 11, 7); 5805 shift_n = DecodeImmShift (type, imm5, shift_t); 5806 5807 // if t == 15 || m == 15 then UNPREDICTABLE; 5808 if ((t == 15) || (m == 15)) 5809 return false; 5810 5811 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5812 if (wback && ((n == 15) || (n == t))) 5813 return false; 5814 } 5815 break; 5816 5817 default: 5818 return false; 5819 } 5820 5821 addr_t offset_addr; 5822 addr_t address; 5823 5824 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5825 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5826 if (!success) 5827 return false; 5828 5829 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 5830 5831 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5832 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5833 if (!success) 5834 return false; 5835 5836 if (add) 5837 offset_addr = Rn + offset; 5838 else 5839 offset_addr = Rn - offset; 5840 5841 // address = if index then offset_addr else R[n]; 5842 if (index) 5843 address = offset_addr; 5844 else 5845 address = Rn; 5846 5847 // R[t] = ZeroExtend(MemU[address,1],32); 5848 Register base_reg; 5849 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5850 5851 EmulateInstruction::Context context; 5852 context.type = eContextRegisterLoad; 5853 context.SetRegisterPlusOffset (base_reg, address - Rn); 5854 5855 uint64_t data = MemURead (context, address, 1, 0, &success); 5856 if (!success) 5857 return false; 5858 5859 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5860 return false; 5861 5862 // if wback then R[n] = offset_addr; 5863 if (wback) 5864 { 5865 context.type = eContextAdjustBaseRegister; 5866 context.SetAddress (offset_addr); 5867 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5868 return false; 5869 } 5870 } 5871 return true; 5872} 5873 5874// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 5875// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 5876// post-indexed, or pre-indexed addressing. 5877bool 5878EmulateInstructionARM::EmulateLDRHImmediate (ARMEncoding encoding) 5879{ 5880#if 0 5881 if ConditionPassed() then 5882 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5883 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5884 address = if index then offset_addr else R[n]; 5885 data = MemU[address,2]; 5886 if wback then R[n] = offset_addr; 5887 if UnalignedSupport() || address<0> = ’0’ then 5888 R[t] = ZeroExtend(data, 32); 5889 else // Can only apply before ARMv7 5890 R[t] = bits(32) UNKNOWN; 5891#endif 5892 5893 5894 bool success = false; 5895 const uint32_t opcode = OpcodeAsUnsigned (&success); 5896 if (!success) 5897 return false; 5898 5899 if (ConditionPassed()) 5900 { 5901 uint32_t t; 5902 uint32_t n; 5903 uint32_t imm32; 5904 bool index; 5905 bool add; 5906 bool wback; 5907 5908 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5909 switch (encoding) 5910 { 5911 case eEncodingT1: 5912 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’0’, 32); 5913 t = Bits32 (opcode, 2, 0); 5914 n = Bits32 (opcode, 5, 3); 5915 imm32 = Bits32 (opcode, 10, 6) << 1; 5916 5917 // index = TRUE; add = TRUE; wback = FALSE; 5918 index = true; 5919 add = true; 5920 wback = false; 5921 5922 break; 5923 5924 case eEncodingT2: 5925 // if Rt == ’1111’ then SEE "Unallocated memory hints"; 5926 // if Rn == ’1111’ then SEE LDRH (literal); 5927 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5928 t = Bits32 (opcode, 15, 12); 5929 n = Bits32 (opcode, 19, 16); 5930 imm32 = Bits32 (opcode, 11, 0); 5931 5932 // index = TRUE; add = TRUE; wback = FALSE; 5933 index = true; 5934 add = true; 5935 wback = false; 5936 5937 // if t == 13 then UNPREDICTABLE; 5938 if (t == 13) 5939 return false; 5940 break; 5941 5942 case eEncodingT3: 5943 // if Rn == ’1111’ then SEE LDRH (literal); 5944 // if Rt == ’1111’ && P == ’1’ && U == ’0’ && W == ’0’ then SEE "Unallocated memory hints"; 5945 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE LDRHT; 5946 // if P == ’0’ && W == ’0’ then UNDEFINED; 5947 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 5948 return false; 5949 5950 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5951 t = Bits32 (opcode, 15, 12); 5952 n = Bits32 (opcode, 19, 16); 5953 imm32 = Bits32 (opcode, 7, 0); 5954 5955 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 5956 index = BitIsSet (opcode, 10); 5957 add = BitIsSet (opcode, 9); 5958 wback = BitIsSet (opcode, 8); 5959 5960 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 5961 if (BadReg (t) || (wback && (n == t))) 5962 return false; 5963 break; 5964 5965 default: 5966 return false; 5967 } 5968 5969 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5970 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5971 if (!success) 5972 return false; 5973 5974 addr_t offset_addr; 5975 addr_t address; 5976 5977 if (add) 5978 offset_addr = Rn + imm32; 5979 else 5980 offset_addr = Rn - imm32; 5981 5982 // address = if index then offset_addr else R[n]; 5983 if (index) 5984 address = offset_addr; 5985 else 5986 address = Rn; 5987 5988 // data = MemU[address,2]; 5989 Register base_reg; 5990 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 5991 5992 EmulateInstruction::Context context; 5993 context.type = eContextRegisterLoad; 5994 context.SetRegisterPlusOffset (base_reg, address - Rn); 5995 5996 uint64_t data = MemURead (context, address, 2, 0, &success); 5997 if (!success) 5998 return false; 5999 6000 // if wback then R[n] = offset_addr; 6001 if (wback) 6002 { 6003 context.type = eContextAdjustBaseRegister; 6004 context.SetAddress (offset_addr); 6005 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6006 return false; 6007 } 6008 6009 // if UnalignedSupport() || address<0> = ’0’ then 6010 if (UnalignedSupport () || BitIsClear (address, 0)) 6011 { 6012 // R[t] = ZeroExtend(data, 32); 6013 context.type = eContextRegisterLoad; 6014 context.SetRegisterPlusOffset (base_reg, address - Rn); 6015 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6016 return false; 6017 } 6018 else // Can only apply before ARMv7 6019 { 6020 // R[t] = bits(32) UNKNOWN; 6021 WriteBits32Unknown (t); 6022 } 6023 } 6024 return true; 6025} 6026 6027// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6028// zero-extends it to form a 32-bit word, and writes it to a register. 6029bool 6030EmulateInstructionARM::EmulateLDRHLiteral (ARMEncoding encoding) 6031{ 6032#if 0 6033 if ConditionPassed() then 6034 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6035 base = Align(PC,4); 6036 address = if add then (base + imm32) else (base - imm32); 6037 data = MemU[address,2]; 6038 if UnalignedSupport() || address<0> = ’0’ then 6039 R[t] = ZeroExtend(data, 32); 6040 else // Can only apply before ARMv7 6041 R[t] = bits(32) UNKNOWN; 6042#endif 6043 6044 bool success = false; 6045 const uint32_t opcode = OpcodeAsUnsigned (&success); 6046 if (!success) 6047 return false; 6048 6049 if (ConditionPassed()) 6050 { 6051 uint32_t t; 6052 uint32_t imm32; 6053 bool add; 6054 6055 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6056 switch (encoding) 6057 { 6058 case eEncodingT1: 6059 // if Rt == ’1111’ then SEE "Unallocated memory hints"; 6060 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’); 6061 t = Bits32 (opcode, 15, 12); 6062 imm32 = Bits32 (opcode, 11, 0); 6063 add = BitIsSet (opcode, 23); 6064 6065 // if t == 13 then UNPREDICTABLE; 6066 if (t == 13) 6067 return false; 6068 6069 break; 6070 6071 case eEncodingA1: 6072 { 6073 uint32_t imm4H = Bits32 (opcode, 11, 8); 6074 uint32_t imm4L = Bits32 (opcode, 3, 0); 6075 6076 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == ’1’); 6077 t = Bits32 (opcode, 15, 12); 6078 imm32 = (imm4H << 4) & imm4L; 6079 add = BitIsSet (opcode, 23); 6080 6081 // if t == 15 then UNPREDICTABLE; 6082 if (t == 15) 6083 return false; 6084 break; 6085 } 6086 6087 default: 6088 return false; 6089 } 6090 6091 // base = Align(PC,4); 6092 uint64_t pc_value = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 6093 if (!success) 6094 return false; 6095 6096 addr_t base = AlignPC (pc_value); 6097 addr_t address; 6098 6099 // address = if add then (base + imm32) else (base - imm32); 6100 if (add) 6101 address = base + imm32; 6102 else 6103 address = base - imm32; 6104 6105 // data = MemU[address,2]; 6106 Register base_reg; 6107 base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 6108 6109 EmulateInstruction::Context context; 6110 context.type = eContextRegisterLoad; 6111 context.SetRegisterPlusOffset (base_reg, address - base); 6112 6113 uint64_t data = MemURead (context, address, 2, 0, &success); 6114 if (!success) 6115 return false; 6116 6117 6118 // if UnalignedSupport() || address<0> = ’0’ then 6119 if (UnalignedSupport () || BitIsClear (address, 0)) 6120 { 6121 // R[t] = ZeroExtend(data, 32); 6122 context.type = eContextRegisterLoad; 6123 context.SetRegisterPlusOffset (base_reg, address - base); 6124 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6125 return false; 6126 6127 } 6128 else // Can only apply before ARMv7 6129 { 6130 // R[t] = bits(32) UNKNOWN; 6131 WriteBits32Unknown (t); 6132 } 6133 } 6134 return true; 6135} 6136 6137// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6138// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6139// be shifted left by 0, 1, 2, or 3 bits. 6140bool 6141EmulateInstructionARM::EmulateLDRHRegister (ARMEncoding encoding) 6142{ 6143#if 0 6144 if ConditionPassed() then 6145 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6146 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6147 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6148 address = if index then offset_addr else R[n]; 6149 data = MemU[address,2]; 6150 if wback then R[n] = offset_addr; 6151 if UnalignedSupport() || address<0> = ’0’ then 6152 R[t] = ZeroExtend(data, 32); 6153 else // Can only apply before ARMv7 6154 R[t] = bits(32) UNKNOWN; 6155#endif 6156 6157 bool success = false; 6158 const uint32_t opcode = OpcodeAsUnsigned (&success); 6159 if (!success) 6160 return false; 6161 6162 if (ConditionPassed()) 6163 { 6164 uint32_t t; 6165 uint32_t n; 6166 uint32_t m; 6167 bool index; 6168 bool add; 6169 bool wback; 6170 ARM_ShifterType shift_t; 6171 uint32_t shift_n; 6172 6173 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6174 switch (encoding) 6175 { 6176 case eEncodingT1: 6177 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6178 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6179 t = Bits32 (opcode, 2, 0); 6180 n = Bits32 (opcode, 5, 3); 6181 m = Bits32 (opcode, 8, 6); 6182 6183 // index = TRUE; add = TRUE; wback = FALSE; 6184 index = true; 6185 add = true; 6186 wback = false; 6187 6188 // (shift_t, shift_n) = (SRType_LSL, 0); 6189 shift_t = SRType_LSL; 6190 shift_n = 0; 6191 6192 break; 6193 6194 case eEncodingT2: 6195 // if Rn == ’1111’ then SEE LDRH (literal); 6196 // if Rt == ’1111’ then SEE "Unallocated memory hints"; 6197 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6198 t = Bits32 (opcode, 15, 12); 6199 n = Bits32 (opcode, 19, 16); 6200 m = Bits32 (opcode, 3, 0); 6201 6202 // index = TRUE; add = TRUE; wback = FALSE; 6203 index = true; 6204 add = true; 6205 wback = false; 6206 6207 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6208 shift_t = SRType_LSL; 6209 shift_n = Bits32 (opcode, 5, 4); 6210 6211 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6212 if ((t == 13) || BadReg (m)) 6213 return false; 6214 break; 6215 6216 case eEncodingA1: 6217 // if P == ’0’ && W == ’1’ then SEE LDRHT; 6218 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6219 t = Bits32 (opcode, 15, 12); 6220 n = Bits32 (opcode, 19, 16); 6221 m = Bits32 (opcode, 3, 0); 6222 6223 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 6224 index = BitIsSet (opcode, 24); 6225 add = BitIsSet (opcode, 23); 6226 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6227 6228 // (shift_t, shift_n) = (SRType_LSL, 0); 6229 shift_t = SRType_LSL; 6230 shift_n = 0; 6231 6232 // if t == 15 || m == 15 then UNPREDICTABLE; 6233 if ((t == 15) || (m == 15)) 6234 return false; 6235 6236 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6237 if (wback && ((n == 15) || (n == t))) 6238 return false; 6239 6240 break; 6241 6242 default: 6243 return false; 6244 } 6245 6246 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6247 6248 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6249 if (!success) 6250 return false; 6251 6252 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 6253 6254 addr_t offset_addr; 6255 addr_t address; 6256 6257 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6258 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6259 if (!success) 6260 return false; 6261 6262 if (add) 6263 offset_addr = Rn + offset; 6264 else 6265 offset_addr = Rn - offset; 6266 6267 // address = if index then offset_addr else R[n]; 6268 if (index) 6269 address = offset_addr; 6270 else 6271 address = Rn; 6272 6273 // data = MemU[address,2]; 6274 Register base_reg; 6275 Register offset_reg; 6276 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 6277 offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 6278 6279 EmulateInstruction::Context context; 6280 context.type = eContextRegisterLoad; 6281 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6282 uint64_t data = MemURead (context, address, 2, 0, &success); 6283 if (!success) 6284 return false; 6285 6286 // if wback then R[n] = offset_addr; 6287 if (wback) 6288 { 6289 context.type = eContextAdjustBaseRegister; 6290 context.SetAddress (offset_addr); 6291 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6292 return false; 6293 } 6294 6295 // if UnalignedSupport() || address<0> = ’0’ then 6296 if (UnalignedSupport() || BitIsClear (address, 0)) 6297 { 6298 // R[t] = ZeroExtend(data, 32); 6299 context.type = eContextRegisterLoad; 6300 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6301 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6302 return false; 6303 } 6304 else // Can only apply before ARMv7 6305 { 6306 // R[t] = bits(32) UNKNOWN; 6307 WriteBits32Unknown (t); 6308 } 6309 } 6310 return true; 6311} 6312 6313// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6314// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6315// or pre-indexed addressing. 6316bool 6317EmulateInstructionARM::EmulateLDRSBImmediate (ARMEncoding encoding) 6318{ 6319#if 0 6320 if ConditionPassed() then 6321 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6322 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6323 address = if index then offset_addr else R[n]; 6324 R[t] = SignExtend(MemU[address,1], 32); 6325 if wback then R[n] = offset_addr; 6326#endif 6327 6328 bool success = false; 6329 const uint32_t opcode = OpcodeAsUnsigned (&success); 6330 if (!success) 6331 return false; 6332 6333 if (ConditionPassed ()) 6334 { 6335 uint32_t t; 6336 uint32_t n; 6337 uint32_t imm32; 6338 bool index; 6339 bool add; 6340 bool wback; 6341 6342 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6343 switch (encoding) 6344 { 6345 case eEncodingT1: 6346 // if Rt == ’1111’ then SEE PLI; 6347 // if Rn == ’1111’ then SEE LDRSB (literal); 6348 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6349 t = Bits32 (opcode, 15, 12); 6350 n = Bits32 (opcode, 19, 16); 6351 imm32 = Bits32 (opcode, 11, 0); 6352 6353 // index = TRUE; add = TRUE; wback = FALSE; 6354 index = true; 6355 add = true; 6356 wback = false; 6357 6358 // if t == 13 then UNPREDICTABLE; 6359 if (t == 13) 6360 return false; 6361 6362 break; 6363 6364 case eEncodingT2: 6365 // if Rt == ’1111’ && P == ’1’ && U == ’0’ && W == ’0’ then SEE PLI; 6366 // if Rn == ’1111’ then SEE LDRSB (literal); 6367 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE LDRSBT; 6368 // if P == ’0’ && W == ’0’ then UNDEFINED; 6369 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6370 return false; 6371 6372 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6373 t = Bits32 (opcode, 15, 12); 6374 n = Bits32 (opcode, 19, 16); 6375 imm32 = Bits32 (opcode, 7, 0); 6376 6377 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 6378 index = BitIsSet (opcode, 10); 6379 add = BitIsSet (opcode, 9); 6380 wback = BitIsSet (opcode, 8); 6381 6382 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6383 if (BadReg (t) || (wback && (n == t))) 6384 return false; 6385 6386 break; 6387 6388 case eEncodingA1: 6389 { 6390 // if Rn == ’1111’ then SEE LDRSB (literal); 6391 // if P == ’0’ && W == ’1’ then SEE LDRSBT; 6392 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6393 t = Bits32 (opcode, 15, 12); 6394 n = Bits32 (opcode, 19, 16); 6395 6396 uint32_t imm4H = Bits32 (opcode, 11, 8); 6397 uint32_t imm4L = Bits32 (opcode, 3, 0); 6398 imm32 = (imm4H << 4) & imm4L; 6399 6400 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 6401 index = BitIsSet (opcode, 24); 6402 add = BitIsSet (opcode, 23); 6403 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6404 6405 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 6406 if ((t == 15) || (wback && (n == t))) 6407 return false; 6408 6409 break; 6410 } 6411 6412 default: 6413 return false; 6414 } 6415 6416 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6417 if (!success) 6418 return false; 6419 6420 addr_t offset_addr; 6421 addr_t address; 6422 6423 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6424 if (add) 6425 offset_addr = Rn + imm32; 6426 else 6427 offset_addr = Rn - imm32; 6428 6429 // address = if index then offset_addr else R[n]; 6430 if (index) 6431 address = offset_addr; 6432 else 6433 address = Rn; 6434 6435 // R[t] = SignExtend(MemU[address,1], 32); 6436 Register base_reg; 6437 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 6438 6439 EmulateInstruction::Context context; 6440 context.type = eContextRegisterLoad; 6441 context.SetRegisterPlusOffset (base_reg, address - Rn); 6442 6443 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 6444 if (!success) 6445 return false; 6446 6447 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 6448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 6449 return false; 6450 6451 // if wback then R[n] = offset_addr; 6452 if (wback) 6453 { 6454 context.type = eContextAdjustBaseRegister; 6455 context.SetAddress (offset_addr); 6456 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6457 return false; 6458 } 6459 } 6460 6461 return true; 6462} 6463 6464// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6465// sign-extends it to form a 32-bit word, and writes tit to a register. 6466bool 6467EmulateInstructionARM::EmulateLDRSBLiteral (ARMEncoding encoding) 6468{ 6469#if 0 6470 if ConditionPassed() then 6471 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6472 base = Align(PC,4); 6473 address = if add then (base + imm32) else (base - imm32); 6474 R[t] = SignExtend(MemU[address,1], 32); 6475#endif 6476 6477 bool success = false; 6478 const uint32_t opcode = OpcodeAsUnsigned (&success); 6479 if (!success) 6480 return false; 6481 6482 if (ConditionPassed ()) 6483 { 6484 uint32_t t; 6485 uint32_t imm32; 6486 bool add; 6487 6488 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6489 switch (encoding) 6490 { 6491 case eEncodingT1: 6492 // if Rt == ’1111’ then SEE PLI; 6493 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’); 6494 t = Bits32 (opcode, 15, 12); 6495 imm32 = Bits32 (opcode, 11, 0); 6496 add = BitIsSet (opcode, 23); 6497 6498 // if t == 13 then UNPREDICTABLE; 6499 if (t == 13) 6500 return false; 6501 6502 break; 6503 6504 case eEncodingA1: 6505 { 6506 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == ’1’); 6507 t = Bits32 (opcode, 15, 12); 6508 uint32_t imm4H = Bits32 (opcode, 11, 8); 6509 uint32_t imm4L = Bits32 (opcode, 3, 0); 6510 imm32 = (imm4H << 4) & imm4L; 6511 add = BitIsSet (opcode, 23); 6512 6513 // if t == 15 then UNPREDICTABLE; 6514 if (t == 15) 6515 return false; 6516 6517 break; 6518 } 6519 6520 default: 6521 return false; 6522 } 6523 6524 // base = Align(PC,4); 6525 uint64_t pc_value = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, 6526 &success); 6527 if (!success) 6528 return false; 6529 uint64_t base = AlignPC (pc_value); 6530 6531 // address = if add then (base + imm32) else (base - imm32); 6532 addr_t address; 6533 if (add) 6534 address = base + imm32; 6535 else 6536 address = base - imm32; 6537 6538 // R[t] = SignExtend(MemU[address,1], 32); 6539 Register base_reg; 6540 base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 6541 6542 EmulateInstruction::Context context; 6543 context.type = eContextRegisterLoad; 6544 context.SetRegisterPlusOffset (base_reg, address - base); 6545 6546 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 6547 if (!success) 6548 return false; 6549 6550 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 6551 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 6552 return false; 6553 } 6554 return true; 6555} 6556 6557// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 6558// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 6559// shifted left by 0, 1, 2, or 3 bits. 6560bool 6561EmulateInstructionARM::EmulateLDRSBRegister (ARMEncoding encoding) 6562{ 6563#if 0 6564 if ConditionPassed() then 6565 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6566 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6567 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6568 address = if index then offset_addr else R[n]; 6569 R[t] = SignExtend(MemU[address,1], 32); 6570 if wback then R[n] = offset_addr; 6571#endif 6572 6573 bool success = false; 6574 const uint32_t opcode = OpcodeAsUnsigned (&success); 6575 if (!success) 6576 return false; 6577 6578 if (ConditionPassed ()) 6579 { 6580 uint32_t t; 6581 uint32_t n; 6582 uint32_t m; 6583 bool index; 6584 bool add; 6585 bool wback; 6586 ARM_ShifterType shift_t; 6587 uint32_t shift_n; 6588 6589 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6590 switch (encoding) 6591 { 6592 case eEncodingT1: 6593 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6594 t = Bits32 (opcode, 2, 0); 6595 n = Bits32 (opcode, 5, 3); 6596 m = Bits32 (opcode, 8, 6); 6597 6598 // index = TRUE; add = TRUE; wback = FALSE; 6599 index = true; 6600 add = true; 6601 wback = false; 6602 6603 // (shift_t, shift_n) = (SRType_LSL, 0); 6604 shift_t = SRType_LSL; 6605 shift_n = 0; 6606 6607 break; 6608 6609 case eEncodingT2: 6610 // if Rt == ’1111’ then SEE PLI; 6611 // if Rn == ’1111’ then SEE LDRSB (literal); 6612 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6613 t = Bits32 (opcode, 15, 12); 6614 n = Bits32 (opcode, 19, 16); 6615 m = Bits32 (opcode, 3, 0); 6616 6617 // index = TRUE; add = TRUE; wback = FALSE; 6618 index = true; 6619 add = true; 6620 wback = false; 6621 6622 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6623 shift_t = SRType_LSL; 6624 shift_n = Bits32 (opcode, 5, 4); 6625 6626 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6627 if ((t == 13) || BadReg (m)) 6628 return false; 6629 break; 6630 6631 case eEncodingA1: 6632 // if P == ’0’ && W == ’1’ then SEE LDRSBT; 6633 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6634 t = Bits32 (opcode, 15, 12); 6635 n = Bits32 (opcode, 19, 16); 6636 m = Bits32 (opcode, 3, 0); 6637 6638 // index = (P == ’1’); add = (U == ’1’); wback = (P == ’0’) || (W == ’1’); 6639 index = BitIsSet (opcode, 24); 6640 add = BitIsSet (opcode, 23); 6641 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 6642 6643 // (shift_t, shift_n) = (SRType_LSL, 0); 6644 shift_t = SRType_LSL; 6645 shift_n = 0; 6646 6647 // if t == 15 || m == 15 then UNPREDICTABLE; 6648 if ((t == 15) || (m == 15)) 6649 return false; 6650 6651 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6652 if (wback && ((n == 15) || (n == t))) 6653 return false; 6654 break; 6655 6656 default: 6657 return false; 6658 } 6659 6660 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6661 if (!success) 6662 return false; 6663 6664 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6665 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); 6666 6667 addr_t offset_addr; 6668 addr_t address; 6669 6670 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6671 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6672 if (!success) 6673 return false; 6674 6675 if (add) 6676 offset_addr = Rn + offset; 6677 else 6678 offset_addr = Rn - offset; 6679 6680 // address = if index then offset_addr else R[n]; 6681 if (index) 6682 address = offset_addr; 6683 else 6684 address = Rn; 6685 6686 // R[t] = SignExtend(MemU[address,1], 32); 6687 Register base_reg; 6688 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 6689 Register offset_reg; 6690 offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); 6691 6692 EmulateInstruction::Context context; 6693 context.type = eContextRegisterLoad; 6694 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6695 6696 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 6697 if (!success) 6698 return false; 6699 6700 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 6701 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 6702 return false; 6703 6704 // if wback then R[n] = offset_addr; 6705 if (wback) 6706 { 6707 context.type = eContextAdjustBaseRegister; 6708 context.SetAddress (offset_addr); 6709 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6710 return false; 6711 } 6712 } 6713 return true; 6714} 6715 6716// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 6717// and writes the result to the destination register. It can optionally update the condition flags based on 6718// the result. 6719bool 6720EmulateInstructionARM::EmulateEORImm (ARMEncoding encoding) 6721{ 6722#if 0 6723 // ARM pseudo code... 6724 if ConditionPassed() then 6725 EncodingSpecificOperations(); 6726 result = R[n] EOR imm32; 6727 if d == 15 then // Can only occur for ARM encoding 6728 ALUWritePC(result); // setflags is always FALSE here 6729 else 6730 R[d] = result; 6731 if setflags then 6732 APSR.N = result<31>; 6733 APSR.Z = IsZeroBit(result); 6734 APSR.C = carry; 6735 // APSR.V unchanged 6736#endif 6737 6738 bool success = false; 6739 const uint32_t opcode = OpcodeAsUnsigned (&success); 6740 if (!success) 6741 return false; 6742 6743 if (ConditionPassed()) 6744 { 6745 uint32_t Rd, Rn; 6746 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 6747 bool setflags; 6748 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6749 switch (encoding) 6750 { 6751 case eEncodingT1: 6752 Rd = Bits32(opcode, 11, 8); 6753 Rn = Bits32(opcode, 19, 16); 6754 setflags = BitIsSet(opcode, 20); 6755 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6756 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 6757 if (Rd == 15 && setflags) 6758 return EmulateTEQImm(eEncodingT1); 6759 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6760 return false; 6761 break; 6762 case eEncodingA1: 6763 Rd = Bits32(opcode, 15, 12); 6764 Rn = Bits32(opcode, 19, 16); 6765 setflags = BitIsSet(opcode, 20); 6766 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6767 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 6768 // TODO: Emulate SUBS PC, LR and related instructions. 6769 if (Rd == 15 && setflags) 6770 return false; 6771 break; 6772 default: 6773 return false; 6774 } 6775 6776 // Read the first operand. 6777 uint32_t val1 = ReadCoreReg(Rn, &success); 6778 if (!success) 6779 return false; 6780 6781 uint32_t result = val1 ^ imm32; 6782 6783 EmulateInstruction::Context context; 6784 context.type = EmulateInstruction::eContextImmediate; 6785 context.SetNoArgs (); 6786 6787 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6788 return false; 6789 } 6790 return true; 6791} 6792 6793// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 6794// optionally-shifted register value, and writes the result to the destination register. 6795// It can optionally update the condition flags based on the result. 6796bool 6797EmulateInstructionARM::EmulateEORReg (ARMEncoding encoding) 6798{ 6799#if 0 6800 // ARM pseudo code... 6801 if ConditionPassed() then 6802 EncodingSpecificOperations(); 6803 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6804 result = R[n] EOR shifted; 6805 if d == 15 then // Can only occur for ARM encoding 6806 ALUWritePC(result); // setflags is always FALSE here 6807 else 6808 R[d] = result; 6809 if setflags then 6810 APSR.N = result<31>; 6811 APSR.Z = IsZeroBit(result); 6812 APSR.C = carry; 6813 // APSR.V unchanged 6814#endif 6815 6816 bool success = false; 6817 const uint32_t opcode = OpcodeAsUnsigned (&success); 6818 if (!success) 6819 return false; 6820 6821 if (ConditionPassed()) 6822 { 6823 uint32_t Rd, Rn, Rm; 6824 ARM_ShifterType shift_t; 6825 uint32_t shift_n; // the shift applied to the value read from Rm 6826 bool setflags; 6827 uint32_t carry; 6828 switch (encoding) 6829 { 6830 case eEncodingT1: 6831 Rd = Rn = Bits32(opcode, 2, 0); 6832 Rm = Bits32(opcode, 5, 3); 6833 setflags = !InITBlock(); 6834 shift_t = SRType_LSL; 6835 shift_n = 0; 6836 break; 6837 case eEncodingT2: 6838 Rd = Bits32(opcode, 11, 8); 6839 Rn = Bits32(opcode, 19, 16); 6840 Rm = Bits32(opcode, 3, 0); 6841 setflags = BitIsSet(opcode, 20); 6842 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6843 // if Rd == '1111' && S == '1' then SEE TEQ (register); 6844 if (Rd == 15 && setflags) 6845 return EmulateTEQReg(eEncodingT1); 6846 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6847 return false; 6848 break; 6849 case eEncodingA1: 6850 Rd = Bits32(opcode, 15, 12); 6851 Rn = Bits32(opcode, 19, 16); 6852 Rm = Bits32(opcode, 3, 0); 6853 setflags = BitIsSet(opcode, 20); 6854 shift_n = DecodeImmShiftARM(opcode, shift_t); 6855 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 6856 // TODO: Emulate SUBS PC, LR and related instructions. 6857 if (Rd == 15 && setflags) 6858 return false; 6859 break; 6860 default: 6861 return false; 6862 } 6863 6864 // Read the first operand. 6865 uint32_t val1 = ReadCoreReg(Rn, &success); 6866 if (!success) 6867 return false; 6868 6869 // Read the second operand. 6870 uint32_t val2 = ReadCoreReg(Rm, &success); 6871 if (!success) 6872 return false; 6873 6874 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 6875 uint32_t result = val1 ^ shifted; 6876 6877 EmulateInstruction::Context context; 6878 context.type = EmulateInstruction::eContextImmediate; 6879 context.SetNoArgs (); 6880 6881 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6882 return false; 6883 } 6884 return true; 6885} 6886 6887// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 6888// writes the result to the destination register. It can optionally update the condition flags based 6889// on the result. 6890bool 6891EmulateInstructionARM::EmulateORRImm (ARMEncoding encoding) 6892{ 6893#if 0 6894 // ARM pseudo code... 6895 if ConditionPassed() then 6896 EncodingSpecificOperations(); 6897 result = R[n] OR imm32; 6898 if d == 15 then // Can only occur for ARM encoding 6899 ALUWritePC(result); // setflags is always FALSE here 6900 else 6901 R[d] = result; 6902 if setflags then 6903 APSR.N = result<31>; 6904 APSR.Z = IsZeroBit(result); 6905 APSR.C = carry; 6906 // APSR.V unchanged 6907#endif 6908 6909 bool success = false; 6910 const uint32_t opcode = OpcodeAsUnsigned (&success); 6911 if (!success) 6912 return false; 6913 6914 if (ConditionPassed()) 6915 { 6916 uint32_t Rd, Rn; 6917 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 6918 bool setflags; 6919 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6920 switch (encoding) 6921 { 6922 case eEncodingT1: 6923 Rd = Bits32(opcode, 11, 8); 6924 Rn = Bits32(opcode, 19, 16); 6925 setflags = BitIsSet(opcode, 20); 6926 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6927 // if Rn == ‘1111’ then SEE MOV (immediate); 6928 if (Rn == 15) 6929 return EmulateMOVRdImm(eEncodingT2); 6930 if (BadReg(Rd) || Rn == 13) 6931 return false; 6932 break; 6933 case eEncodingA1: 6934 Rd = Bits32(opcode, 15, 12); 6935 Rn = Bits32(opcode, 19, 16); 6936 setflags = BitIsSet(opcode, 20); 6937 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6938 // TODO: Emulate SUBS PC, LR and related instructions. 6939 if (Rd == 15 && setflags) 6940 return false; 6941 break; 6942 default: 6943 return false; 6944 } 6945 6946 // Read the first operand. 6947 uint32_t val1 = ReadCoreReg(Rn, &success); 6948 if (!success) 6949 return false; 6950 6951 uint32_t result = val1 | imm32; 6952 6953 EmulateInstruction::Context context; 6954 context.type = EmulateInstruction::eContextImmediate; 6955 context.SetNoArgs (); 6956 6957 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6958 return false; 6959 } 6960 return true; 6961} 6962 6963// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 6964// value, and writes the result to the destination register. It can optionally update the condition flags based 6965// on the result. 6966bool 6967EmulateInstructionARM::EmulateORRReg (ARMEncoding encoding) 6968{ 6969#if 0 6970 // ARM pseudo code... 6971 if ConditionPassed() then 6972 EncodingSpecificOperations(); 6973 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6974 result = R[n] OR shifted; 6975 if d == 15 then // Can only occur for ARM encoding 6976 ALUWritePC(result); // setflags is always FALSE here 6977 else 6978 R[d] = result; 6979 if setflags then 6980 APSR.N = result<31>; 6981 APSR.Z = IsZeroBit(result); 6982 APSR.C = carry; 6983 // APSR.V unchanged 6984#endif 6985 6986 bool success = false; 6987 const uint32_t opcode = OpcodeAsUnsigned (&success); 6988 if (!success) 6989 return false; 6990 6991 if (ConditionPassed()) 6992 { 6993 uint32_t Rd, Rn, Rm; 6994 ARM_ShifterType shift_t; 6995 uint32_t shift_n; // the shift applied to the value read from Rm 6996 bool setflags; 6997 uint32_t carry; 6998 switch (encoding) 6999 { 7000 case eEncodingT1: 7001 Rd = Rn = Bits32(opcode, 2, 0); 7002 Rm = Bits32(opcode, 5, 3); 7003 setflags = !InITBlock(); 7004 shift_t = SRType_LSL; 7005 shift_n = 0; 7006 break; 7007 case eEncodingT2: 7008 Rd = Bits32(opcode, 11, 8); 7009 Rn = Bits32(opcode, 19, 16); 7010 Rm = Bits32(opcode, 3, 0); 7011 setflags = BitIsSet(opcode, 20); 7012 shift_n = DecodeImmShiftThumb(opcode, shift_t); 7013 // if Rn == '1111' then SEE MOV (register); 7014 if (Rn == 15) 7015 return EmulateMOVRdRm(eEncodingT3); 7016 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 7017 return false; 7018 break; 7019 case eEncodingA1: 7020 Rd = Bits32(opcode, 15, 12); 7021 Rn = Bits32(opcode, 19, 16); 7022 Rm = Bits32(opcode, 3, 0); 7023 setflags = BitIsSet(opcode, 20); 7024 shift_n = DecodeImmShiftARM(opcode, shift_t); 7025 // TODO: Emulate SUBS PC, LR and related instructions. 7026 if (Rd == 15 && setflags) 7027 return false; 7028 break; 7029 default: 7030 return false; 7031 } 7032 7033 // Read the first operand. 7034 uint32_t val1 = ReadCoreReg(Rn, &success); 7035 if (!success) 7036 return false; 7037 7038 // Read the second operand. 7039 uint32_t val2 = ReadCoreReg(Rm, &success); 7040 if (!success) 7041 return false; 7042 7043 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 7044 uint32_t result = val1 | shifted; 7045 7046 EmulateInstruction::Context context; 7047 context.type = EmulateInstruction::eContextImmediate; 7048 context.SetNoArgs (); 7049 7050 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 7051 return false; 7052 } 7053 return true; 7054} 7055 7056// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 7057// the destination register. It can optionally update the condition flags based on the result. 7058bool 7059EmulateInstructionARM::EmulateRSBImm (ARMEncoding encoding) 7060{ 7061#if 0 7062 // ARM pseudo code... 7063 if ConditionPassed() then 7064 EncodingSpecificOperations(); 7065 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 7066 if d == 15 then // Can only occur for ARM encoding 7067 ALUWritePC(result); // setflags is always FALSE here 7068 else 7069 R[d] = result; 7070 if setflags then 7071 APSR.N = result<31>; 7072 APSR.Z = IsZeroBit(result); 7073 APSR.C = carry; 7074 APSR.V = overflow; 7075#endif 7076 7077 bool success = false; 7078 const uint32_t opcode = OpcodeAsUnsigned (&success); 7079 if (!success) 7080 return false; 7081 7082 uint32_t Rd; // the destination register 7083 uint32_t Rn; // the first operand 7084 bool setflags; 7085 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 7086 switch (encoding) { 7087 case eEncodingT1: 7088 Rd = Bits32(opcode, 2, 0); 7089 Rn = Bits32(opcode, 5, 3); 7090 setflags = !InITBlock(); 7091 imm32 = 0; 7092 break; 7093 case eEncodingT2: 7094 Rd = Bits32(opcode, 11, 8); 7095 Rn = Bits32(opcode, 19, 16); 7096 setflags = BitIsSet(opcode, 20); 7097 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 7098 if (BadReg(Rd) || BadReg(Rn)) 7099 return false; 7100 break; 7101 case eEncodingA1: 7102 Rd = Bits32(opcode, 15, 12); 7103 Rn = Bits32(opcode, 19, 16); 7104 setflags = BitIsSet(opcode, 20); 7105 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 7106 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7107 // TODO: Emulate SUBS PC, LR and related instructions. 7108 if (Rd == 15 && setflags) 7109 return false; 7110 break; 7111 default: 7112 return false; 7113 } 7114 // Read the register value from the operand register Rn. 7115 uint32_t reg_val = ReadCoreReg(Rn, &success); 7116 if (!success) 7117 return false; 7118 7119 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 7120 7121 EmulateInstruction::Context context; 7122 context.type = EmulateInstruction::eContextImmediate; 7123 context.SetNoArgs (); 7124 7125 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7126 return false; 7127 7128 return true; 7129} 7130 7131// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 7132// result to the destination register. It can optionally update the condition flags based on the result. 7133bool 7134EmulateInstructionARM::EmulateRSBReg (ARMEncoding encoding) 7135{ 7136#if 0 7137 // ARM pseudo code... 7138 if ConditionPassed() then 7139 EncodingSpecificOperations(); 7140 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 7141 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 7142 if d == 15 then // Can only occur for ARM encoding 7143 ALUWritePC(result); // setflags is always FALSE here 7144 else 7145 R[d] = result; 7146 if setflags then 7147 APSR.N = result<31>; 7148 APSR.Z = IsZeroBit(result); 7149 APSR.C = carry; 7150 APSR.V = overflow; 7151#endif 7152 7153 bool success = false; 7154 const uint32_t opcode = OpcodeAsUnsigned (&success); 7155 if (!success) 7156 return false; 7157 7158 uint32_t Rd; // the destination register 7159 uint32_t Rn; // the first operand 7160 uint32_t Rm; // the second operand 7161 bool setflags; 7162 ARM_ShifterType shift_t; 7163 uint32_t shift_n; // the shift applied to the value read from Rm 7164 switch (encoding) { 7165 case eEncodingT1: 7166 Rd = Bits32(opcode, 11, 8); 7167 Rn = Bits32(opcode, 19, 16); 7168 Rm = Bits32(opcode, 3, 0); 7169 setflags = BitIsSet(opcode, 20); 7170 shift_n = DecodeImmShiftThumb(opcode, shift_t); 7171 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 7172 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 7173 return false; 7174 break; 7175 case eEncodingA1: 7176 Rd = Bits32(opcode, 15, 12); 7177 Rn = Bits32(opcode, 19, 16); 7178 Rm = Bits32(opcode, 3, 0); 7179 setflags = BitIsSet(opcode, 20); 7180 shift_n = DecodeImmShiftARM(opcode, shift_t); 7181 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7182 // TODO: Emulate SUBS PC, LR and related instructions. 7183 if (Rd == 15 && setflags) 7184 return false; 7185 break; 7186 default: 7187 return false; 7188 } 7189 // Read the register value from register Rn. 7190 uint32_t val1 = ReadCoreReg(Rn, &success); 7191 if (!success) 7192 return false; 7193 7194 // Read the register value from register Rm. 7195 uint32_t val2 = ReadCoreReg(Rm, &success); 7196 if (!success) 7197 return false; 7198 7199 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 7200 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 7201 7202 EmulateInstruction::Context context; 7203 context.type = EmulateInstruction::eContextImmediate; 7204 context.SetNoArgs(); 7205 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7206 return false; 7207 7208 return true; 7209} 7210 7211// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 7212// an immediate value, and writes the result to the destination register. It can optionally update the condition 7213// flags based on the result. 7214bool 7215EmulateInstructionARM::EmulateRSCImm (ARMEncoding encoding) 7216{ 7217#if 0 7218 // ARM pseudo code... 7219 if ConditionPassed() then 7220 EncodingSpecificOperations(); 7221 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 7222 if d == 15 then 7223 ALUWritePC(result); // setflags is always FALSE here 7224 else 7225 R[d] = result; 7226 if setflags then 7227 APSR.N = result<31>; 7228 APSR.Z = IsZeroBit(result); 7229 APSR.C = carry; 7230 APSR.V = overflow; 7231#endif 7232 7233 bool success = false; 7234 const uint32_t opcode = OpcodeAsUnsigned (&success); 7235 if (!success) 7236 return false; 7237 7238 uint32_t Rd; // the destination register 7239 uint32_t Rn; // the first operand 7240 bool setflags; 7241 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 7242 switch (encoding) { 7243 case eEncodingA1: 7244 Rd = Bits32(opcode, 15, 12); 7245 Rn = Bits32(opcode, 19, 16); 7246 setflags = BitIsSet(opcode, 20); 7247 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 7248 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7249 // TODO: Emulate SUBS PC, LR and related instructions. 7250 if (Rd == 15 && setflags) 7251 return false; 7252 break; 7253 default: 7254 return false; 7255 } 7256 // Read the register value from the operand register Rn. 7257 uint32_t reg_val = ReadCoreReg(Rn, &success); 7258 if (!success) 7259 return false; 7260 7261 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 7262 7263 EmulateInstruction::Context context; 7264 context.type = EmulateInstruction::eContextImmediate; 7265 context.SetNoArgs (); 7266 7267 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7268 return false; 7269 7270 return true; 7271} 7272 7273// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 7274// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 7275// condition flags based on the result. 7276bool 7277EmulateInstructionARM::EmulateRSCReg (ARMEncoding encoding) 7278{ 7279#if 0 7280 // ARM pseudo code... 7281 if ConditionPassed() then 7282 EncodingSpecificOperations(); 7283 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 7284 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 7285 if d == 15 then 7286 ALUWritePC(result); // setflags is always FALSE here 7287 else 7288 R[d] = result; 7289 if setflags then 7290 APSR.N = result<31>; 7291 APSR.Z = IsZeroBit(result); 7292 APSR.C = carry; 7293 APSR.V = overflow; 7294#endif 7295 7296 bool success = false; 7297 const uint32_t opcode = OpcodeAsUnsigned (&success); 7298 if (!success) 7299 return false; 7300 7301 uint32_t Rd; // the destination register 7302 uint32_t Rn; // the first operand 7303 uint32_t Rm; // the second operand 7304 bool setflags; 7305 ARM_ShifterType shift_t; 7306 uint32_t shift_n; // the shift applied to the value read from Rm 7307 switch (encoding) { 7308 case eEncodingA1: 7309 Rd = Bits32(opcode, 15, 12); 7310 Rn = Bits32(opcode, 19, 16); 7311 Rm = Bits32(opcode, 3, 0); 7312 setflags = BitIsSet(opcode, 20); 7313 shift_n = DecodeImmShiftARM(opcode, shift_t); 7314 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7315 // TODO: Emulate SUBS PC, LR and related instructions. 7316 if (Rd == 15 && setflags) 7317 return false; 7318 break; 7319 default: 7320 return false; 7321 } 7322 // Read the register value from register Rn. 7323 uint32_t val1 = ReadCoreReg(Rn, &success); 7324 if (!success) 7325 return false; 7326 7327 // Read the register value from register Rm. 7328 uint32_t val2 = ReadCoreReg(Rm, &success); 7329 if (!success) 7330 return false; 7331 7332 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 7333 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 7334 7335 EmulateInstruction::Context context; 7336 context.type = EmulateInstruction::eContextImmediate; 7337 context.SetNoArgs(); 7338 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7339 return false; 7340 7341 return true; 7342} 7343 7344// Subtract with Carry (immediate) subtracts an immediate value and the value of 7345// NOT (Carry flag) from a register value, and writes the result to the destination register. 7346// It can optionally update the condition flags based on the result. 7347bool 7348EmulateInstructionARM::EmulateSBCImm (ARMEncoding encoding) 7349{ 7350#if 0 7351 // ARM pseudo code... 7352 if ConditionPassed() then 7353 EncodingSpecificOperations(); 7354 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 7355 if d == 15 then // Can only occur for ARM encoding 7356 ALUWritePC(result); // setflags is always FALSE here 7357 else 7358 R[d] = result; 7359 if setflags then 7360 APSR.N = result<31>; 7361 APSR.Z = IsZeroBit(result); 7362 APSR.C = carry; 7363 APSR.V = overflow; 7364#endif 7365 7366 bool success = false; 7367 const uint32_t opcode = OpcodeAsUnsigned (&success); 7368 if (!success) 7369 return false; 7370 7371 uint32_t Rd; // the destination register 7372 uint32_t Rn; // the first operand 7373 bool setflags; 7374 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 7375 switch (encoding) { 7376 case eEncodingT1: 7377 Rd = Bits32(opcode, 11, 8); 7378 Rn = Bits32(opcode, 19, 16); 7379 setflags = BitIsSet(opcode, 20); 7380 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 7381 if (BadReg(Rd) || BadReg(Rn)) 7382 return false; 7383 break; 7384 case eEncodingA1: 7385 Rd = Bits32(opcode, 15, 12); 7386 Rn = Bits32(opcode, 19, 16); 7387 setflags = BitIsSet(opcode, 20); 7388 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 7389 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7390 // TODO: Emulate SUBS PC, LR and related instructions. 7391 if (Rd == 15 && setflags) 7392 return false; 7393 break; 7394 default: 7395 return false; 7396 } 7397 // Read the register value from the operand register Rn. 7398 uint32_t reg_val = ReadCoreReg(Rn, &success); 7399 if (!success) 7400 return false; 7401 7402 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 7403 7404 EmulateInstruction::Context context; 7405 context.type = EmulateInstruction::eContextImmediate; 7406 context.SetNoArgs (); 7407 7408 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7409 return false; 7410 7411 return true; 7412} 7413 7414// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 7415// NOT (Carry flag) from a register value, and writes the result to the destination register. 7416// It can optionally update the condition flags based on the result. 7417bool 7418EmulateInstructionARM::EmulateSBCReg (ARMEncoding encoding) 7419{ 7420#if 0 7421 // ARM pseudo code... 7422 if ConditionPassed() then 7423 EncodingSpecificOperations(); 7424 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 7425 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 7426 if d == 15 then // Can only occur for ARM encoding 7427 ALUWritePC(result); // setflags is always FALSE here 7428 else 7429 R[d] = result; 7430 if setflags then 7431 APSR.N = result<31>; 7432 APSR.Z = IsZeroBit(result); 7433 APSR.C = carry; 7434 APSR.V = overflow; 7435#endif 7436 7437 bool success = false; 7438 const uint32_t opcode = OpcodeAsUnsigned (&success); 7439 if (!success) 7440 return false; 7441 7442 uint32_t Rd; // the destination register 7443 uint32_t Rn; // the first operand 7444 uint32_t Rm; // the second operand 7445 bool setflags; 7446 ARM_ShifterType shift_t; 7447 uint32_t shift_n; // the shift applied to the value read from Rm 7448 switch (encoding) { 7449 case eEncodingT1: 7450 Rd = Rn = Bits32(opcode, 2, 0); 7451 Rm = Bits32(opcode, 5, 3); 7452 setflags = !InITBlock(); 7453 shift_t = SRType_LSL; 7454 shift_n = 0; 7455 break; 7456 case eEncodingT2: 7457 Rd = Bits32(opcode, 11, 8); 7458 Rn = Bits32(opcode, 19, 16); 7459 Rm = Bits32(opcode, 3, 0); 7460 setflags = BitIsSet(opcode, 20); 7461 shift_n = DecodeImmShiftThumb(opcode, shift_t); 7462 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 7463 return false; 7464 break; 7465 case eEncodingA1: 7466 Rd = Bits32(opcode, 15, 12); 7467 Rn = Bits32(opcode, 19, 16); 7468 Rm = Bits32(opcode, 3, 0); 7469 setflags = BitIsSet(opcode, 20); 7470 shift_n = DecodeImmShiftARM(opcode, shift_t); 7471 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7472 // TODO: Emulate SUBS PC, LR and related instructions. 7473 if (Rd == 15 && setflags) 7474 return false; 7475 break; 7476 default: 7477 return false; 7478 } 7479 // Read the register value from register Rn. 7480 uint32_t val1 = ReadCoreReg(Rn, &success); 7481 if (!success) 7482 return false; 7483 7484 // Read the register value from register Rm. 7485 uint32_t val2 = ReadCoreReg(Rm, &success); 7486 if (!success) 7487 return false; 7488 7489 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); 7490 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 7491 7492 EmulateInstruction::Context context; 7493 context.type = EmulateInstruction::eContextImmediate; 7494 context.SetNoArgs(); 7495 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7496 return false; 7497 7498 return true; 7499} 7500 7501// This instruction subtracts an immediate value from a register value, and writes the result 7502// to the destination register. It can optionally update the condition flags based on the result. 7503bool 7504EmulateInstructionARM::EmulateSUBImmThumb (ARMEncoding encoding) 7505{ 7506#if 0 7507 // ARM pseudo code... 7508 if ConditionPassed() then 7509 EncodingSpecificOperations(); 7510 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 7511 R[d] = result; 7512 if setflags then 7513 APSR.N = result<31>; 7514 APSR.Z = IsZeroBit(result); 7515 APSR.C = carry; 7516 APSR.V = overflow; 7517#endif 7518 7519 bool success = false; 7520 const uint32_t opcode = OpcodeAsUnsigned (&success); 7521 if (!success) 7522 return false; 7523 7524 uint32_t Rd; // the destination register 7525 uint32_t Rn; // the first operand 7526 bool setflags; 7527 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 7528 switch (encoding) { 7529 case eEncodingT1: 7530 Rd = Bits32(opcode, 2, 0); 7531 Rn = Bits32(opcode, 5, 3); 7532 setflags = !InITBlock(); 7533 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 7534 break; 7535 case eEncodingT2: 7536 Rd = Rn = Bits32(opcode, 10, 8); 7537 setflags = !InITBlock(); 7538 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 7539 break; 7540 case eEncodingT3: 7541 Rd = Bits32(opcode, 11, 8); 7542 Rn = Bits32(opcode, 19, 16); 7543 setflags = BitIsSet(opcode, 20); 7544 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 7545 7546 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 7547 if (Rd == 15 && setflags) 7548 return EmulateCMPImm(eEncodingT2); 7549 7550 // if Rn == ‘1101’ then SEE SUB (SP minus immediate); 7551 if (Rn == 13) 7552 return EmulateSUBSPImm(eEncodingT2); 7553 7554 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 7555 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 7556 return false; 7557 break; 7558 case eEncodingT4: 7559 Rd = Bits32(opcode, 11, 8); 7560 Rn = Bits32(opcode, 19, 16); 7561 setflags = BitIsSet(opcode, 20); 7562 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 7563 7564 // if Rn == '1111' then SEE ADR; 7565 if (Rn == 15) 7566 return EmulateADR(eEncodingT2); 7567 7568 // if Rn == '1101' then SEE SUB (SP minus immediate); 7569 if (Rn == 13) 7570 return EmulateSUBSPImm(eEncodingT3); 7571 7572 if (BadReg(Rd)) 7573 return false; 7574 break; 7575 default: 7576 return false; 7577 } 7578 // Read the register value from the operand register Rn. 7579 uint32_t reg_val = ReadCoreReg(Rn, &success); 7580 if (!success) 7581 return false; 7582 7583 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 7584 7585 EmulateInstruction::Context context; 7586 context.type = EmulateInstruction::eContextImmediate; 7587 context.SetNoArgs (); 7588 7589 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7590 return false; 7591 7592 return true; 7593} 7594 7595// This instruction subtracts an immediate value from a register value, and writes the result 7596// to the destination register. It can optionally update the condition flags based on the result. 7597bool 7598EmulateInstructionARM::EmulateSUBImmARM (ARMEncoding encoding) 7599{ 7600#if 0 7601 // ARM pseudo code... 7602 if ConditionPassed() then 7603 EncodingSpecificOperations(); 7604 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 7605 if d == 15 then 7606 ALUWritePC(result); // setflags is always FALSE here 7607 else 7608 R[d] = result; 7609 if setflags then 7610 APSR.N = result<31>; 7611 APSR.Z = IsZeroBit(result); 7612 APSR.C = carry; 7613 APSR.V = overflow; 7614#endif 7615 7616 bool success = false; 7617 const uint32_t opcode = OpcodeAsUnsigned (&success); 7618 if (!success) 7619 return false; 7620 7621 uint32_t Rd; // the destination register 7622 uint32_t Rn; // the first operand 7623 bool setflags; 7624 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 7625 switch (encoding) { 7626 case eEncodingA1: 7627 Rd = Bits32(opcode, 15, 12); 7628 Rn = Bits32(opcode, 19, 16); 7629 setflags = BitIsSet(opcode, 20); 7630 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 7631 7632 // if Rn == ‘1111’ && S == ‘0’ then SEE ADR; 7633 if (Rn == 15 && !setflags) 7634 return EmulateADR(eEncodingA2); 7635 7636 // if Rn == ‘1101’ then SEE SUB (SP minus immediate); 7637 if (Rn == 13) 7638 return EmulateSUBSPImm(eEncodingA1); 7639 7640 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 7641 // TODO: Emulate SUBS PC, LR and related instructions. 7642 if (Rd == 15 && setflags) 7643 return false; 7644 break; 7645 default: 7646 return false; 7647 } 7648 // Read the register value from the operand register Rn. 7649 uint32_t reg_val = ReadCoreReg(Rn, &success); 7650 if (!success) 7651 return false; 7652 7653 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 7654 7655 EmulateInstruction::Context context; 7656 context.type = EmulateInstruction::eContextImmediate; 7657 context.SetNoArgs (); 7658 7659 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 7660 return false; 7661 7662 return true; 7663} 7664 7665// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 7666// immediate value. It updates the condition flags based on the result, and discards the result. 7667bool 7668EmulateInstructionARM::EmulateTEQImm (ARMEncoding encoding) 7669{ 7670#if 0 7671 // ARM pseudo code... 7672 if ConditionPassed() then 7673 EncodingSpecificOperations(); 7674 result = R[n] EOR imm32; 7675 APSR.N = result<31>; 7676 APSR.Z = IsZeroBit(result); 7677 APSR.C = carry; 7678 // APSR.V unchanged 7679#endif 7680 7681 bool success = false; 7682 const uint32_t opcode = OpcodeAsUnsigned (&success); 7683 if (!success) 7684 return false; 7685 7686 if (ConditionPassed()) 7687 { 7688 uint32_t Rn; 7689 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 7690 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 7691 switch (encoding) 7692 { 7693 case eEncodingT1: 7694 Rn = Bits32(opcode, 19, 16); 7695 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 7696 if (BadReg(Rn)) 7697 return false; 7698 break; 7699 case eEncodingA1: 7700 Rn = Bits32(opcode, 19, 16); 7701 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 7702 break; 7703 default: 7704 return false; 7705 } 7706 7707 // Read the first operand. 7708 uint32_t val1 = ReadCoreReg(Rn, &success); 7709 if (!success) 7710 return false; 7711 7712 uint32_t result = val1 ^ imm32; 7713 7714 EmulateInstruction::Context context; 7715 context.type = EmulateInstruction::eContextImmediate; 7716 context.SetNoArgs (); 7717 7718 if (!WriteFlags(context, result, carry)) 7719 return false; 7720 } 7721 return true; 7722} 7723 7724// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 7725// optionally-shifted register value. It updates the condition flags based on the result, and discards 7726// the result. 7727bool 7728EmulateInstructionARM::EmulateTEQReg (ARMEncoding encoding) 7729{ 7730#if 0 7731 // ARM pseudo code... 7732 if ConditionPassed() then 7733 EncodingSpecificOperations(); 7734 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 7735 result = R[n] EOR shifted; 7736 APSR.N = result<31>; 7737 APSR.Z = IsZeroBit(result); 7738 APSR.C = carry; 7739 // APSR.V unchanged 7740#endif 7741 7742 bool success = false; 7743 const uint32_t opcode = OpcodeAsUnsigned (&success); 7744 if (!success) 7745 return false; 7746 7747 if (ConditionPassed()) 7748 { 7749 uint32_t Rn, Rm; 7750 ARM_ShifterType shift_t; 7751 uint32_t shift_n; // the shift applied to the value read from Rm 7752 uint32_t carry; 7753 switch (encoding) 7754 { 7755 case eEncodingT1: 7756 Rn = Bits32(opcode, 19, 16); 7757 Rm = Bits32(opcode, 3, 0); 7758 shift_n = DecodeImmShiftThumb(opcode, shift_t); 7759 if (BadReg(Rn) || BadReg(Rm)) 7760 return false; 7761 break; 7762 case eEncodingA1: 7763 Rn = Bits32(opcode, 19, 16); 7764 Rm = Bits32(opcode, 3, 0); 7765 shift_n = DecodeImmShiftARM(opcode, shift_t); 7766 break; 7767 default: 7768 return false; 7769 } 7770 7771 // Read the first operand. 7772 uint32_t val1 = ReadCoreReg(Rn, &success); 7773 if (!success) 7774 return false; 7775 7776 // Read the second operand. 7777 uint32_t val2 = ReadCoreReg(Rm, &success); 7778 if (!success) 7779 return false; 7780 7781 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 7782 uint32_t result = val1 ^ shifted; 7783 7784 EmulateInstruction::Context context; 7785 context.type = EmulateInstruction::eContextImmediate; 7786 context.SetNoArgs (); 7787 7788 if (!WriteFlags(context, result, carry)) 7789 return false; 7790 } 7791 return true; 7792} 7793 7794// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 7795// It updates the condition flags based on the result, and discards the result. 7796bool 7797EmulateInstructionARM::EmulateTSTImm (ARMEncoding encoding) 7798{ 7799#if 0 7800 // ARM pseudo code... 7801 if ConditionPassed() then 7802 EncodingSpecificOperations(); 7803 result = R[n] AND imm32; 7804 APSR.N = result<31>; 7805 APSR.Z = IsZeroBit(result); 7806 APSR.C = carry; 7807 // APSR.V unchanged 7808#endif 7809 7810 bool success = false; 7811 const uint32_t opcode = OpcodeAsUnsigned (&success); 7812 if (!success) 7813 return false; 7814 7815 if (ConditionPassed()) 7816 { 7817 uint32_t Rn; 7818 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 7819 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 7820 switch (encoding) 7821 { 7822 case eEncodingT1: 7823 Rn = Bits32(opcode, 19, 16); 7824 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 7825 if (BadReg(Rn)) 7826 return false; 7827 break; 7828 case eEncodingA1: 7829 Rn = Bits32(opcode, 19, 16); 7830 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 7831 break; 7832 default: 7833 return false; 7834 } 7835 7836 // Read the first operand. 7837 uint32_t val1 = ReadCoreReg(Rn, &success); 7838 if (!success) 7839 return false; 7840 7841 uint32_t result = val1 & imm32; 7842 7843 EmulateInstruction::Context context; 7844 context.type = EmulateInstruction::eContextImmediate; 7845 context.SetNoArgs (); 7846 7847 if (!WriteFlags(context, result, carry)) 7848 return false; 7849 } 7850 return true; 7851} 7852 7853// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 7854// It updates the condition flags based on the result, and discards the result. 7855bool 7856EmulateInstructionARM::EmulateTSTReg (ARMEncoding encoding) 7857{ 7858#if 0 7859 // ARM pseudo code... 7860 if ConditionPassed() then 7861 EncodingSpecificOperations(); 7862 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 7863 result = R[n] AND shifted; 7864 APSR.N = result<31>; 7865 APSR.Z = IsZeroBit(result); 7866 APSR.C = carry; 7867 // APSR.V unchanged 7868#endif 7869 7870 bool success = false; 7871 const uint32_t opcode = OpcodeAsUnsigned (&success); 7872 if (!success) 7873 return false; 7874 7875 if (ConditionPassed()) 7876 { 7877 uint32_t Rn, Rm; 7878 ARM_ShifterType shift_t; 7879 uint32_t shift_n; // the shift applied to the value read from Rm 7880 uint32_t carry; 7881 switch (encoding) 7882 { 7883 case eEncodingT1: 7884 Rn = Bits32(opcode, 2, 0); 7885 Rm = Bits32(opcode, 5, 3); 7886 shift_t = SRType_LSL; 7887 shift_n = 0; 7888 break; 7889 case eEncodingT2: 7890 Rn = Bits32(opcode, 19, 16); 7891 Rm = Bits32(opcode, 3, 0); 7892 shift_n = DecodeImmShiftThumb(opcode, shift_t); 7893 if (BadReg(Rn) || BadReg(Rm)) 7894 return false; 7895 break; 7896 case eEncodingA1: 7897 Rn = Bits32(opcode, 19, 16); 7898 Rm = Bits32(opcode, 3, 0); 7899 shift_n = DecodeImmShiftARM(opcode, shift_t); 7900 break; 7901 default: 7902 return false; 7903 } 7904 7905 // Read the first operand. 7906 uint32_t val1 = ReadCoreReg(Rn, &success); 7907 if (!success) 7908 return false; 7909 7910 // Read the second operand. 7911 uint32_t val2 = ReadCoreReg(Rm, &success); 7912 if (!success) 7913 return false; 7914 7915 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); 7916 uint32_t result = val1 & shifted; 7917 7918 EmulateInstruction::Context context; 7919 context.type = EmulateInstruction::eContextImmediate; 7920 context.SetNoArgs (); 7921 7922 if (!WriteFlags(context, result, carry)) 7923 return false; 7924 } 7925 return true; 7926} 7927 7928EmulateInstructionARM::ARMOpcode* 7929EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 7930{ 7931 static ARMOpcode 7932 g_arm_opcodes[] = 7933 { 7934 //---------------------------------------------------------------------- 7935 // Prologue instructions 7936 //---------------------------------------------------------------------- 7937 7938 // push register(s) 7939 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 7940 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 7941 7942 // set r7 to point to a stack offset 7943 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 7944 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 7945 // copy the stack pointer to ip 7946 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 7947 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 7948 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 7949 7950 // adjust the stack pointer 7951 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 7952 7953 // push one register 7954 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 7955 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 7956 7957 // vector push consecutive extension register(s) 7958 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 7959 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 7960 7961 //---------------------------------------------------------------------- 7962 // Epilogue instructions 7963 //---------------------------------------------------------------------- 7964 7965 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 7966 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 7967 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 7968 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 7969 7970 //---------------------------------------------------------------------- 7971 // Supervisor Call (previously Software Interrupt) 7972 //---------------------------------------------------------------------- 7973 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 7974 7975 //---------------------------------------------------------------------- 7976 // Branch instructions 7977 //---------------------------------------------------------------------- 7978 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 7979 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 7980 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 7981 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 7982 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 7983 // for example, "bx lr" 7984 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 7985 // bxj 7986 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 7987 7988 //---------------------------------------------------------------------- 7989 // Data-processing instructions 7990 //---------------------------------------------------------------------- 7991 // adc (immediate) 7992 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 7993 // adc (register) 7994 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 7995 // add (immediate) 7996 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 7997 // add (register) 7998 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 7999 // adr 8000 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 8001 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 8002 // and (immediate) 8003 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 8004 // and (register) 8005 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8006 // bic (immediate) 8007 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 8008 // bic (register) 8009 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8010 // eor (immediate) 8011 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 8012 // eor (register) 8013 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8014 // orr (immediate) 8015 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 8016 // orr (register) 8017 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8018 // rsb (immediate) 8019 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 8020 // rsb (register) 8021 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8022 // rsc (immediate) 8023 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 8024 // rsc (register) 8025 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8026 // sbc (immediate) 8027 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 8028 // sbc (register) 8029 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 8030 // sub (immediate, ARM) 8031 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 8032 // sub (sp minus immediate) 8033 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 8034 // teq (immediate) 8035 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 8036 // teq (register) 8037 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 8038 // tst (immediate) 8039 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 8040 // tst (register) 8041 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 8042 8043 8044 // mov (register) 8045 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 8046 // mvn (immediate) 8047 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 8048 // mvn (register) 8049 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 8050 // cmn (immediate) 8051 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 8052 // cmn (register) 8053 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 8054 // cmp (immediate) 8055 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 8056 // cmp (register) 8057 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 8058 // asr (immediate) 8059 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 8060 // asr (register) 8061 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 8062 // lsl (immediate) 8063 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 8064 // lsl (register) 8065 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 8066 // lsr (immediate) 8067 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 8068 // lsr (register) 8069 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 8070 // rrx is a special case encoding of ror (immediate) 8071 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 8072 // ror (immediate) 8073 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 8074 // ror (register) 8075 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 8076 8077 //---------------------------------------------------------------------- 8078 // Load instructions 8079 //---------------------------------------------------------------------- 8080 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 8081 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 8082 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 8083 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 8084 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 8085 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 8086 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 8087 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 8088 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 8089 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 8090 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 8091 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 8092 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 8093 8094 //---------------------------------------------------------------------- 8095 // Store instructions 8096 //---------------------------------------------------------------------- 8097 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 8098 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 8099 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 8100 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 8101 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" } 8102 8103 8104 }; 8105 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 8106 8107 for (size_t i=0; i<k_num_arm_opcodes; ++i) 8108 { 8109 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 8110 return &g_arm_opcodes[i]; 8111 } 8112 return NULL; 8113} 8114 8115 8116EmulateInstructionARM::ARMOpcode* 8117EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 8118{ 8119 8120 static ARMOpcode 8121 g_thumb_opcodes[] = 8122 { 8123 //---------------------------------------------------------------------- 8124 // Prologue instructions 8125 //---------------------------------------------------------------------- 8126 8127 // push register(s) 8128 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 8129 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 8130 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 8131 8132 // set r7 to point to a stack offset 8133 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 8134 // copy the stack pointer to r7 8135 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 8136 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 8137 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 8138 8139 // PC-relative load into register (see also EmulateADDSPRm) 8140 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 8141 8142 // adjust the stack pointer 8143 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 8144 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 8145 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 8146 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 8147 8148 // vector push consecutive extension register(s) 8149 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 8150 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 8151 8152 //---------------------------------------------------------------------- 8153 // Epilogue instructions 8154 //---------------------------------------------------------------------- 8155 8156 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 8157 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 8158 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 8159 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 8160 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 8161 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 8162 8163 //---------------------------------------------------------------------- 8164 // Supervisor Call (previously Software Interrupt) 8165 //---------------------------------------------------------------------- 8166 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 8167 8168 //---------------------------------------------------------------------- 8169 // If Then makes up to four following instructions conditional. 8170 //---------------------------------------------------------------------- 8171 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 8172 8173 //---------------------------------------------------------------------- 8174 // Branch instructions 8175 //---------------------------------------------------------------------- 8176 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 8177 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 8178 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 8179 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 8180 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 8181 // J1 == J2 == 1 8182 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 8183 // J1 == J2 == 1 8184 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 8185 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 8186 // for example, "bx lr" 8187 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 8188 // bxj 8189 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 8190 // compare and branch 8191 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 8192 // table branch byte 8193 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 8194 // table branch halfword 8195 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 8196 8197 //---------------------------------------------------------------------- 8198 // Data-processing instructions 8199 //---------------------------------------------------------------------- 8200 // adc (immediate) 8201 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 8202 // adc (register) 8203 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 8204 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8205 // add (register) 8206 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 8207 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 8208 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 8209 // adr 8210 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 8211 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 8212 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 8213 // and (immediate) 8214 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 8215 // and (register) 8216 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 8217 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8218 // bic (immediate) 8219 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 8220 // bic (register) 8221 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 8222 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8223 // eor (immediate) 8224 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 8225 // eor (register) 8226 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 8227 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8228 // orr (immediate) 8229 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 8230 // orr (register) 8231 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 8232 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8233 // rsb (immediate) 8234 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 8235 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 8236 // rsb (register) 8237 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8238 // sbc (immediate) 8239 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 8240 // sbc (register) 8241 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 8242 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 8243 // sub (immediate, Thumb) 8244 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 8245 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 8246 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 8247 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 8248 // sub (sp minus immediate) 8249 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 8250 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 8251 // teq (immediate) 8252 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 8253 // teq (register) 8254 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 8255 // tst (immediate) 8256 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 8257 // tst (register) 8258 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 8259 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 8260 8261 8262 // move from high register to high register 8263 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 8264 // move from low register to low register 8265 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 8266 // mov{s}<c>.w <Rd>, <Rm> 8267 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 8268 // move immediate 8269 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 8270 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 8271 // mvn (immediate) 8272 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 8273 // mvn (register) 8274 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 8275 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 8276 // cmn (immediate) 8277 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 8278 // cmn (register) 8279 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 8280 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 8281 // cmp (immediate) 8282 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 8283 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 8284 // cmp (register) (Rn and Rm both from r0-r7) 8285 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 8286 // cmp (register) (Rn and Rm not both from r0-r7) 8287 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 8288 // asr (immediate) 8289 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 8290 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 8291 // asr (register) 8292 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 8293 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 8294 // lsl (immediate) 8295 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 8296 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 8297 // lsl (register) 8298 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 8299 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 8300 // lsr (immediate) 8301 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 8302 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 8303 // lsr (register) 8304 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 8305 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 8306 // rrx is a special case encoding of ror (immediate) 8307 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 8308 // ror (immediate) 8309 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 8310 // ror (register) 8311 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 8312 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 8313 8314 //---------------------------------------------------------------------- 8315 // Load instructions 8316 //---------------------------------------------------------------------- 8317 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 8318 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 8319 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 8320 { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 8321 // Thumb2 PC-relative load into register 8322 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 8323 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 8324 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 8325 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 8326 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 8327 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[>Rn>, #+/-<imm8>]{!}" }, 8328 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 8329 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 8330 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, eSize32,&EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 8331 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 8332 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 8333 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 8334 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 8335 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 8336 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 8337 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 8338 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 8339 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 8340 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 8341 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 8342 8343 //---------------------------------------------------------------------- 8344 // Store instructions 8345 //---------------------------------------------------------------------- 8346 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 8347 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 8348 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 8349 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 8350 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 8351 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 8352 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 8353 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 8354 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 8355 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 8356 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 8357 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" } 8358 }; 8359 8360 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 8361 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 8362 { 8363 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 8364 return &g_thumb_opcodes[i]; 8365 } 8366 return NULL; 8367} 8368 8369bool 8370EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 8371{ 8372 m_arm_isa = 0; 8373 const char *arch_cstr = arch.GetArchitectureName (); 8374 if (arch_cstr) 8375 { 8376 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 8377 else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 8378 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 8379 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 8380 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 8381 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 8382 else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 8383 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 8384 else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 8385 else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 8386 } 8387 return m_arm_isa != 0; 8388} 8389 8390 8391bool 8392EmulateInstructionARM::ReadInstruction () 8393{ 8394 bool success = false; 8395 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 8396 if (success) 8397 { 8398 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 8399 if (success) 8400 { 8401 Context read_inst_context; 8402 read_inst_context.type = eContextReadOpcode; 8403 read_inst_context.SetNoArgs (); 8404 8405 if (m_inst_cpsr & MASK_CPSR_T) 8406 { 8407 m_inst_mode = eModeThumb; 8408 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 8409 8410 if (success) 8411 { 8412 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 8413 { 8414 m_inst.opcode_type = eOpcode16; 8415 m_inst.opcode.inst16 = thumb_opcode; 8416 } 8417 else 8418 { 8419 m_inst.opcode_type = eOpcode32; 8420 m_inst.opcode.inst32 = (thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success); 8421 } 8422 } 8423 } 8424 else 8425 { 8426 m_inst_mode = eModeARM; 8427 m_inst.opcode_type = eOpcode32; 8428 m_inst.opcode.inst32 = MemARead(read_inst_context, pc, 4, 0, &success); 8429 } 8430 } 8431 } 8432 if (!success) 8433 { 8434 m_inst_mode = eModeInvalid; 8435 m_inst_pc = LLDB_INVALID_ADDRESS; 8436 } 8437 return success; 8438} 8439 8440uint32_t 8441EmulateInstructionARM::ArchVersion () 8442{ 8443 return m_arm_isa; 8444} 8445 8446bool 8447EmulateInstructionARM::ConditionPassed () 8448{ 8449 if (m_inst_cpsr == 0) 8450 return false; 8451 8452 const uint32_t cond = CurrentCond (); 8453 8454 if (cond == UINT32_MAX) 8455 return false; 8456 8457 bool result = false; 8458 switch (UnsignedBits(cond, 3, 1)) 8459 { 8460 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 8461 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 8462 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 8463 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 8464 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 8465 case 5: 8466 { 8467 bool n = (m_inst_cpsr & MASK_CPSR_N); 8468 bool v = (m_inst_cpsr & MASK_CPSR_V); 8469 result = n == v; 8470 } 8471 break; 8472 case 6: 8473 { 8474 bool n = (m_inst_cpsr & MASK_CPSR_N); 8475 bool v = (m_inst_cpsr & MASK_CPSR_V); 8476 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 8477 } 8478 break; 8479 case 7: 8480 result = true; 8481 break; 8482 } 8483 8484 if (cond & 1) 8485 result = !result; 8486 return result; 8487} 8488 8489uint32_t 8490EmulateInstructionARM::CurrentCond () 8491{ 8492 switch (m_inst_mode) 8493 { 8494 default: 8495 case eModeInvalid: 8496 break; 8497 8498 case eModeARM: 8499 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 8500 8501 case eModeThumb: 8502 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 8503 // 'cond' field of the encoding. 8504 if (m_inst.opcode_type == eOpcode16 && 8505 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 8506 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 8507 { 8508 return Bits32(m_inst.opcode.inst16, 11, 7); 8509 } 8510 else if (m_inst.opcode_type == eOpcode32 && 8511 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 8512 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 8513 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 8514 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 8515 { 8516 return Bits32(m_inst.opcode.inst32, 25, 22); 8517 } 8518 8519 return m_it_session.GetCond(); 8520 } 8521 return UINT32_MAX; // Return invalid value 8522} 8523 8524bool 8525EmulateInstructionARM::InITBlock() 8526{ 8527 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 8528} 8529 8530bool 8531EmulateInstructionARM::LastInITBlock() 8532{ 8533 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 8534} 8535 8536bool 8537EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 8538{ 8539 addr_t target; 8540 8541 // Check the current instruction set. 8542 if (CurrentInstrSet() == eModeARM) 8543 target = addr & 0xfffffffc; 8544 else 8545 target = addr & 0xfffffffe; 8546 8547 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 8548 return false; 8549 8550 return true; 8551} 8552 8553// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 8554bool 8555EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 8556{ 8557 addr_t target; 8558 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 8559 // we want to record it and issue a WriteRegister callback so the clients 8560 // can track the mode changes accordingly. 8561 bool cpsr_changed = false; 8562 8563 if (BitIsSet(addr, 0)) 8564 { 8565 if (CurrentInstrSet() != eModeThumb) 8566 { 8567 SelectInstrSet(eModeThumb); 8568 cpsr_changed = true; 8569 } 8570 target = addr & 0xfffffffe; 8571 context.SetMode (eModeThumb); 8572 } 8573 else if (BitIsClear(addr, 1)) 8574 { 8575 if (CurrentInstrSet() != eModeARM) 8576 { 8577 SelectInstrSet(eModeARM); 8578 cpsr_changed = true; 8579 } 8580 target = addr & 0xfffffffc; 8581 context.SetMode (eModeARM); 8582 } 8583 else 8584 return false; // address<1:0> == '10' => UNPREDICTABLE 8585 8586 if (cpsr_changed) 8587 { 8588 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 8589 return false; 8590 } 8591 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 8592 return false; 8593 8594 return true; 8595} 8596 8597// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 8598bool 8599EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 8600{ 8601 if (ArchVersion() >= ARMv5T) 8602 return BXWritePC(context, addr); 8603 else 8604 return BranchWritePC((const Context)context, addr); 8605} 8606 8607// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 8608bool 8609EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 8610{ 8611 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 8612 return BXWritePC(context, addr); 8613 else 8614 return BranchWritePC((const Context)context, addr); 8615} 8616 8617EmulateInstructionARM::Mode 8618EmulateInstructionARM::CurrentInstrSet () 8619{ 8620 return m_inst_mode; 8621} 8622 8623// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 8624// ReadInstruction() is performed. This function has a side effect of updating 8625// the m_new_inst_cpsr member variable if necessary. 8626bool 8627EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 8628{ 8629 m_new_inst_cpsr = m_inst_cpsr; 8630 switch (arm_or_thumb) 8631 { 8632 default: 8633 return false; 8634 eModeARM: 8635 // Clear the T bit. 8636 m_new_inst_cpsr &= ~MASK_CPSR_T; 8637 break; 8638 eModeThumb: 8639 // Set the T bit. 8640 m_new_inst_cpsr |= MASK_CPSR_T; 8641 break; 8642 } 8643 return true; 8644} 8645 8646// This function returns TRUE if the processor currently provides support for 8647// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 8648// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 8649bool 8650EmulateInstructionARM::UnalignedSupport() 8651{ 8652 return (ArchVersion() >= ARMv7); 8653} 8654 8655// The main addition and subtraction instructions can produce status information 8656// about both unsigned carry and signed overflow conditions. This status 8657// information can be used to synthesize multi-word additions and subtractions. 8658EmulateInstructionARM::AddWithCarryResult 8659EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 8660{ 8661 uint32_t result; 8662 uint8_t carry_out; 8663 uint8_t overflow; 8664 8665 uint64_t unsigned_sum = x + y + carry_in; 8666 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 8667 8668 result = UnsignedBits(unsigned_sum, 31, 0); 8669 carry_out = (result == unsigned_sum ? 0 : 1); 8670 overflow = ((int32_t)result == signed_sum ? 0 : 1); 8671 8672 AddWithCarryResult res = { result, carry_out, overflow }; 8673 return res; 8674} 8675 8676uint32_t 8677EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 8678{ 8679 uint32_t reg_kind, reg_num; 8680 switch (num) 8681 { 8682 case SP_REG: 8683 reg_kind = eRegisterKindGeneric; 8684 reg_num = LLDB_REGNUM_GENERIC_SP; 8685 break; 8686 case LR_REG: 8687 reg_kind = eRegisterKindGeneric; 8688 reg_num = LLDB_REGNUM_GENERIC_RA; 8689 break; 8690 case PC_REG: 8691 reg_kind = eRegisterKindGeneric; 8692 reg_num = LLDB_REGNUM_GENERIC_PC; 8693 break; 8694 default: 8695 if (0 <= num && num < SP_REG) 8696 { 8697 reg_kind = eRegisterKindDWARF; 8698 reg_num = dwarf_r0 + num; 8699 } 8700 else 8701 { 8702 assert(0 && "Invalid register number"); 8703 *success = false; 8704 return ~0u; 8705 } 8706 break; 8707 } 8708 8709 // Read our register. 8710 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 8711 8712 // When executing an ARM instruction , PC reads as the address of the current 8713 // instruction plus 8. 8714 // When executing a Thumb instruction , PC reads as the address of the current 8715 // instruction plus 4. 8716 if (num == 15) 8717 { 8718 if (CurrentInstrSet() == eModeARM) 8719 val += 8; 8720 else 8721 val += 4; 8722 } 8723 8724 return val; 8725} 8726 8727// Write the result to the ARM core register Rd, and optionally update the 8728// condition flags based on the result. 8729// 8730// This helper method tries to encapsulate the following pseudocode from the 8731// ARM Architecture Reference Manual: 8732// 8733// if d == 15 then // Can only occur for encoding A1 8734// ALUWritePC(result); // setflags is always FALSE here 8735// else 8736// R[d] = result; 8737// if setflags then 8738// APSR.N = result<31>; 8739// APSR.Z = IsZeroBit(result); 8740// APSR.C = carry; 8741// // APSR.V unchanged 8742// 8743// In the above case, the API client does not pass in the overflow arg, which 8744// defaults to ~0u. 8745bool 8746EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 8747 const uint32_t result, 8748 const uint32_t Rd, 8749 bool setflags, 8750 const uint32_t carry, 8751 const uint32_t overflow) 8752{ 8753 if (Rd == 15) 8754 { 8755 if (!ALUWritePC (context, result)) 8756 return false; 8757 } 8758 else 8759 { 8760 uint32_t reg_kind, reg_num; 8761 switch (Rd) 8762 { 8763 case SP_REG: 8764 reg_kind = eRegisterKindGeneric; 8765 reg_num = LLDB_REGNUM_GENERIC_SP; 8766 break; 8767 case LR_REG: 8768 reg_kind = eRegisterKindGeneric; 8769 reg_num = LLDB_REGNUM_GENERIC_RA; 8770 break; 8771 default: 8772 reg_kind = eRegisterKindDWARF; 8773 reg_num = dwarf_r0 + Rd; 8774 } 8775 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 8776 return false; 8777 if (setflags) 8778 return WriteFlags (context, result, carry, overflow); 8779 } 8780 return true; 8781} 8782 8783// This helper method tries to encapsulate the following pseudocode from the 8784// ARM Architecture Reference Manual: 8785// 8786// APSR.N = result<31>; 8787// APSR.Z = IsZeroBit(result); 8788// APSR.C = carry; 8789// APSR.V = overflow 8790// 8791// Default arguments can be specified for carry and overflow parameters, which means 8792// not to update the respective flags. 8793bool 8794EmulateInstructionARM::WriteFlags (Context &context, 8795 const uint32_t result, 8796 const uint32_t carry, 8797 const uint32_t overflow) 8798{ 8799 m_new_inst_cpsr = m_inst_cpsr; 8800 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 8801 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 8802 if (carry != ~0u) 8803 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 8804 if (overflow != ~0u) 8805 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 8806 if (m_new_inst_cpsr != m_inst_cpsr) 8807 { 8808 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 8809 return false; 8810 } 8811 return true; 8812} 8813 8814bool 8815EmulateInstructionARM::EvaluateInstruction () 8816{ 8817 // Advance the ITSTATE bits to their values for the next instruction. 8818 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 8819 m_it_session.ITAdvance(); 8820 8821 return false; 8822} 8823