1 //===-- EmulateInstructionMIPS.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 "EmulateInstructionMIPS.h" 11 12 #include <stdlib.h> 13 14 #include "lldb/Core/Address.h" 15 #include "lldb/Core/ArchSpec.h" 16 #include "lldb/Core/Opcode.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/RegisterValue.h" 19 #include "lldb/Symbol/UnwindPlan.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Utility/ConstString.h" 22 #include "lldb/Utility/DataExtractor.h" 23 #include "lldb/Utility/Stream.h" 24 #include "llvm-c/Disassembler.h" 25 #include "llvm/MC/MCAsmInfo.h" 26 #include "llvm/MC/MCContext.h" 27 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 28 #include "llvm/MC/MCInst.h" 29 #include "llvm/MC/MCInstrInfo.h" 30 #include "llvm/MC/MCRegisterInfo.h" 31 #include "llvm/MC/MCSubtargetInfo.h" 32 #include "llvm/Support/TargetRegistry.h" 33 #include "llvm/Support/TargetSelect.h" 34 35 #include "llvm/ADT/STLExtras.h" 36 37 #include "Plugins/Process/Utility/InstructionUtils.h" 38 #include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 #define UInt(x) ((uint64_t)x) 44 #define integer int64_t 45 46 //---------------------------------------------------------------------- 47 // 48 // EmulateInstructionMIPS implementation 49 // 50 //---------------------------------------------------------------------- 51 52 #ifdef __mips__ 53 extern "C" { 54 void LLVMInitializeMipsTargetInfo(); 55 void LLVMInitializeMipsTarget(); 56 void LLVMInitializeMipsAsmPrinter(); 57 void LLVMInitializeMipsTargetMC(); 58 void LLVMInitializeMipsDisassembler(); 59 } 60 #endif 61 62 EmulateInstructionMIPS::EmulateInstructionMIPS( 63 const lldb_private::ArchSpec &arch) 64 : EmulateInstruction(arch) { 65 /* Create instance of llvm::MCDisassembler */ 66 std::string Status; 67 llvm::Triple triple = arch.GetTriple(); 68 const llvm::Target *target = 69 llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status); 70 71 /* 72 * If we fail to get the target then we haven't registered it. The 73 * SystemInitializerCommon 74 * does not initialize targets, MCs and disassemblers. However we need the 75 * MCDisassembler 76 * to decode the instructions so that the decoding complexity stays with LLVM. 77 * Initialize the MIPS targets and disassemblers. 78 */ 79 #ifdef __mips__ 80 if (!target) { 81 LLVMInitializeMipsTargetInfo(); 82 LLVMInitializeMipsTarget(); 83 LLVMInitializeMipsAsmPrinter(); 84 LLVMInitializeMipsTargetMC(); 85 LLVMInitializeMipsDisassembler(); 86 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status); 87 } 88 #endif 89 90 assert(target); 91 92 llvm::StringRef cpu; 93 94 switch (arch.GetCore()) { 95 case ArchSpec::eCore_mips32: 96 case ArchSpec::eCore_mips32el: 97 cpu = "mips32"; 98 break; 99 case ArchSpec::eCore_mips32r2: 100 case ArchSpec::eCore_mips32r2el: 101 cpu = "mips32r2"; 102 break; 103 case ArchSpec::eCore_mips32r3: 104 case ArchSpec::eCore_mips32r3el: 105 cpu = "mips32r3"; 106 break; 107 case ArchSpec::eCore_mips32r5: 108 case ArchSpec::eCore_mips32r5el: 109 cpu = "mips32r5"; 110 break; 111 case ArchSpec::eCore_mips32r6: 112 case ArchSpec::eCore_mips32r6el: 113 cpu = "mips32r6"; 114 break; 115 case ArchSpec::eCore_mips64: 116 case ArchSpec::eCore_mips64el: 117 cpu = "mips64"; 118 break; 119 case ArchSpec::eCore_mips64r2: 120 case ArchSpec::eCore_mips64r2el: 121 cpu = "mips64r2"; 122 break; 123 case ArchSpec::eCore_mips64r3: 124 case ArchSpec::eCore_mips64r3el: 125 cpu = "mips64r3"; 126 break; 127 case ArchSpec::eCore_mips64r5: 128 case ArchSpec::eCore_mips64r5el: 129 cpu = "mips64r5"; 130 break; 131 case ArchSpec::eCore_mips64r6: 132 case ArchSpec::eCore_mips64r6el: 133 cpu = "mips64r6"; 134 break; 135 default: 136 cpu = "generic"; 137 break; 138 } 139 140 std::string features = ""; 141 uint32_t arch_flags = arch.GetFlags(); 142 if (arch_flags & ArchSpec::eMIPSAse_msa) 143 features += "+msa,"; 144 if (arch_flags & ArchSpec::eMIPSAse_dsp) 145 features += "+dsp,"; 146 if (arch_flags & ArchSpec::eMIPSAse_dspr2) 147 features += "+dspr2,"; 148 149 m_reg_info.reset(target->createMCRegInfo(triple.getTriple())); 150 assert(m_reg_info.get()); 151 152 m_insn_info.reset(target->createMCInstrInfo()); 153 assert(m_insn_info.get()); 154 155 m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple())); 156 m_subtype_info.reset( 157 target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); 158 assert(m_asm_info.get() && m_subtype_info.get()); 159 160 m_context.reset( 161 new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr)); 162 assert(m_context.get()); 163 164 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); 165 assert(m_disasm.get()); 166 167 /* Create alternate disassembler for microMIPS */ 168 if (arch_flags & ArchSpec::eMIPSAse_mips16) 169 features += "+mips16,"; 170 else if (arch_flags & ArchSpec::eMIPSAse_micromips) 171 features += "+micromips,"; 172 173 m_alt_subtype_info.reset( 174 target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); 175 assert(m_alt_subtype_info.get()); 176 177 m_alt_disasm.reset( 178 target->createMCDisassembler(*m_alt_subtype_info, *m_context)); 179 assert(m_alt_disasm.get()); 180 181 m_next_inst_size = 0; 182 m_use_alt_disaasm = false; 183 } 184 185 void EmulateInstructionMIPS::Initialize() { 186 PluginManager::RegisterPlugin(GetPluginNameStatic(), 187 GetPluginDescriptionStatic(), CreateInstance); 188 } 189 190 void EmulateInstructionMIPS::Terminate() { 191 PluginManager::UnregisterPlugin(CreateInstance); 192 } 193 194 ConstString EmulateInstructionMIPS::GetPluginNameStatic() { 195 ConstString g_plugin_name("lldb.emulate-instruction.mips32"); 196 return g_plugin_name; 197 } 198 199 lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() { 200 static ConstString g_plugin_name("EmulateInstructionMIPS"); 201 return g_plugin_name; 202 } 203 204 const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() { 205 return "Emulate instructions for the MIPS32 architecture."; 206 } 207 208 EmulateInstruction * 209 EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch, 210 InstructionType inst_type) { 211 if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic( 212 inst_type)) { 213 if (arch.GetTriple().getArch() == llvm::Triple::mips || 214 arch.GetTriple().getArch() == llvm::Triple::mipsel) { 215 return new EmulateInstructionMIPS(arch); 216 } 217 } 218 219 return NULL; 220 } 221 222 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) { 223 if (arch.GetTriple().getArch() == llvm::Triple::mips || 224 arch.GetTriple().getArch() == llvm::Triple::mipsel) 225 return true; 226 return false; 227 } 228 229 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num, 230 bool alternate_name) { 231 if (alternate_name) { 232 switch (reg_num) { 233 case dwarf_sp_mips: 234 return "r29"; 235 case dwarf_r30_mips: 236 return "r30"; 237 case dwarf_ra_mips: 238 return "r31"; 239 case dwarf_f0_mips: 240 return "f0"; 241 case dwarf_f1_mips: 242 return "f1"; 243 case dwarf_f2_mips: 244 return "f2"; 245 case dwarf_f3_mips: 246 return "f3"; 247 case dwarf_f4_mips: 248 return "f4"; 249 case dwarf_f5_mips: 250 return "f5"; 251 case dwarf_f6_mips: 252 return "f6"; 253 case dwarf_f7_mips: 254 return "f7"; 255 case dwarf_f8_mips: 256 return "f8"; 257 case dwarf_f9_mips: 258 return "f9"; 259 case dwarf_f10_mips: 260 return "f10"; 261 case dwarf_f11_mips: 262 return "f11"; 263 case dwarf_f12_mips: 264 return "f12"; 265 case dwarf_f13_mips: 266 return "f13"; 267 case dwarf_f14_mips: 268 return "f14"; 269 case dwarf_f15_mips: 270 return "f15"; 271 case dwarf_f16_mips: 272 return "f16"; 273 case dwarf_f17_mips: 274 return "f17"; 275 case dwarf_f18_mips: 276 return "f18"; 277 case dwarf_f19_mips: 278 return "f19"; 279 case dwarf_f20_mips: 280 return "f20"; 281 case dwarf_f21_mips: 282 return "f21"; 283 case dwarf_f22_mips: 284 return "f22"; 285 case dwarf_f23_mips: 286 return "f23"; 287 case dwarf_f24_mips: 288 return "f24"; 289 case dwarf_f25_mips: 290 return "f25"; 291 case dwarf_f26_mips: 292 return "f26"; 293 case dwarf_f27_mips: 294 return "f27"; 295 case dwarf_f28_mips: 296 return "f28"; 297 case dwarf_f29_mips: 298 return "f29"; 299 case dwarf_f30_mips: 300 return "f30"; 301 case dwarf_f31_mips: 302 return "f31"; 303 case dwarf_w0_mips: 304 return "w0"; 305 case dwarf_w1_mips: 306 return "w1"; 307 case dwarf_w2_mips: 308 return "w2"; 309 case dwarf_w3_mips: 310 return "w3"; 311 case dwarf_w4_mips: 312 return "w4"; 313 case dwarf_w5_mips: 314 return "w5"; 315 case dwarf_w6_mips: 316 return "w6"; 317 case dwarf_w7_mips: 318 return "w7"; 319 case dwarf_w8_mips: 320 return "w8"; 321 case dwarf_w9_mips: 322 return "w9"; 323 case dwarf_w10_mips: 324 return "w10"; 325 case dwarf_w11_mips: 326 return "w11"; 327 case dwarf_w12_mips: 328 return "w12"; 329 case dwarf_w13_mips: 330 return "w13"; 331 case dwarf_w14_mips: 332 return "w14"; 333 case dwarf_w15_mips: 334 return "w15"; 335 case dwarf_w16_mips: 336 return "w16"; 337 case dwarf_w17_mips: 338 return "w17"; 339 case dwarf_w18_mips: 340 return "w18"; 341 case dwarf_w19_mips: 342 return "w19"; 343 case dwarf_w20_mips: 344 return "w20"; 345 case dwarf_w21_mips: 346 return "w21"; 347 case dwarf_w22_mips: 348 return "w22"; 349 case dwarf_w23_mips: 350 return "w23"; 351 case dwarf_w24_mips: 352 return "w24"; 353 case dwarf_w25_mips: 354 return "w25"; 355 case dwarf_w26_mips: 356 return "w26"; 357 case dwarf_w27_mips: 358 return "w27"; 359 case dwarf_w28_mips: 360 return "w28"; 361 case dwarf_w29_mips: 362 return "w29"; 363 case dwarf_w30_mips: 364 return "w30"; 365 case dwarf_w31_mips: 366 return "w31"; 367 case dwarf_mir_mips: 368 return "mir"; 369 case dwarf_mcsr_mips: 370 return "mcsr"; 371 case dwarf_config5_mips: 372 return "config5"; 373 default: 374 break; 375 } 376 return nullptr; 377 } 378 379 switch (reg_num) { 380 case dwarf_zero_mips: 381 return "r0"; 382 case dwarf_r1_mips: 383 return "r1"; 384 case dwarf_r2_mips: 385 return "r2"; 386 case dwarf_r3_mips: 387 return "r3"; 388 case dwarf_r4_mips: 389 return "r4"; 390 case dwarf_r5_mips: 391 return "r5"; 392 case dwarf_r6_mips: 393 return "r6"; 394 case dwarf_r7_mips: 395 return "r7"; 396 case dwarf_r8_mips: 397 return "r8"; 398 case dwarf_r9_mips: 399 return "r9"; 400 case dwarf_r10_mips: 401 return "r10"; 402 case dwarf_r11_mips: 403 return "r11"; 404 case dwarf_r12_mips: 405 return "r12"; 406 case dwarf_r13_mips: 407 return "r13"; 408 case dwarf_r14_mips: 409 return "r14"; 410 case dwarf_r15_mips: 411 return "r15"; 412 case dwarf_r16_mips: 413 return "r16"; 414 case dwarf_r17_mips: 415 return "r17"; 416 case dwarf_r18_mips: 417 return "r18"; 418 case dwarf_r19_mips: 419 return "r19"; 420 case dwarf_r20_mips: 421 return "r20"; 422 case dwarf_r21_mips: 423 return "r21"; 424 case dwarf_r22_mips: 425 return "r22"; 426 case dwarf_r23_mips: 427 return "r23"; 428 case dwarf_r24_mips: 429 return "r24"; 430 case dwarf_r25_mips: 431 return "r25"; 432 case dwarf_r26_mips: 433 return "r26"; 434 case dwarf_r27_mips: 435 return "r27"; 436 case dwarf_gp_mips: 437 return "gp"; 438 case dwarf_sp_mips: 439 return "sp"; 440 case dwarf_r30_mips: 441 return "fp"; 442 case dwarf_ra_mips: 443 return "ra"; 444 case dwarf_sr_mips: 445 return "sr"; 446 case dwarf_lo_mips: 447 return "lo"; 448 case dwarf_hi_mips: 449 return "hi"; 450 case dwarf_bad_mips: 451 return "bad"; 452 case dwarf_cause_mips: 453 return "cause"; 454 case dwarf_pc_mips: 455 return "pc"; 456 case dwarf_f0_mips: 457 return "f0"; 458 case dwarf_f1_mips: 459 return "f1"; 460 case dwarf_f2_mips: 461 return "f2"; 462 case dwarf_f3_mips: 463 return "f3"; 464 case dwarf_f4_mips: 465 return "f4"; 466 case dwarf_f5_mips: 467 return "f5"; 468 case dwarf_f6_mips: 469 return "f6"; 470 case dwarf_f7_mips: 471 return "f7"; 472 case dwarf_f8_mips: 473 return "f8"; 474 case dwarf_f9_mips: 475 return "f9"; 476 case dwarf_f10_mips: 477 return "f10"; 478 case dwarf_f11_mips: 479 return "f11"; 480 case dwarf_f12_mips: 481 return "f12"; 482 case dwarf_f13_mips: 483 return "f13"; 484 case dwarf_f14_mips: 485 return "f14"; 486 case dwarf_f15_mips: 487 return "f15"; 488 case dwarf_f16_mips: 489 return "f16"; 490 case dwarf_f17_mips: 491 return "f17"; 492 case dwarf_f18_mips: 493 return "f18"; 494 case dwarf_f19_mips: 495 return "f19"; 496 case dwarf_f20_mips: 497 return "f20"; 498 case dwarf_f21_mips: 499 return "f21"; 500 case dwarf_f22_mips: 501 return "f22"; 502 case dwarf_f23_mips: 503 return "f23"; 504 case dwarf_f24_mips: 505 return "f24"; 506 case dwarf_f25_mips: 507 return "f25"; 508 case dwarf_f26_mips: 509 return "f26"; 510 case dwarf_f27_mips: 511 return "f27"; 512 case dwarf_f28_mips: 513 return "f28"; 514 case dwarf_f29_mips: 515 return "f29"; 516 case dwarf_f30_mips: 517 return "f30"; 518 case dwarf_f31_mips: 519 return "f31"; 520 case dwarf_fcsr_mips: 521 return "fcsr"; 522 case dwarf_fir_mips: 523 return "fir"; 524 case dwarf_w0_mips: 525 return "w0"; 526 case dwarf_w1_mips: 527 return "w1"; 528 case dwarf_w2_mips: 529 return "w2"; 530 case dwarf_w3_mips: 531 return "w3"; 532 case dwarf_w4_mips: 533 return "w4"; 534 case dwarf_w5_mips: 535 return "w5"; 536 case dwarf_w6_mips: 537 return "w6"; 538 case dwarf_w7_mips: 539 return "w7"; 540 case dwarf_w8_mips: 541 return "w8"; 542 case dwarf_w9_mips: 543 return "w9"; 544 case dwarf_w10_mips: 545 return "w10"; 546 case dwarf_w11_mips: 547 return "w11"; 548 case dwarf_w12_mips: 549 return "w12"; 550 case dwarf_w13_mips: 551 return "w13"; 552 case dwarf_w14_mips: 553 return "w14"; 554 case dwarf_w15_mips: 555 return "w15"; 556 case dwarf_w16_mips: 557 return "w16"; 558 case dwarf_w17_mips: 559 return "w17"; 560 case dwarf_w18_mips: 561 return "w18"; 562 case dwarf_w19_mips: 563 return "w19"; 564 case dwarf_w20_mips: 565 return "w20"; 566 case dwarf_w21_mips: 567 return "w21"; 568 case dwarf_w22_mips: 569 return "w22"; 570 case dwarf_w23_mips: 571 return "w23"; 572 case dwarf_w24_mips: 573 return "w24"; 574 case dwarf_w25_mips: 575 return "w25"; 576 case dwarf_w26_mips: 577 return "w26"; 578 case dwarf_w27_mips: 579 return "w27"; 580 case dwarf_w28_mips: 581 return "w28"; 582 case dwarf_w29_mips: 583 return "w29"; 584 case dwarf_w30_mips: 585 return "w30"; 586 case dwarf_w31_mips: 587 return "w31"; 588 case dwarf_mcsr_mips: 589 return "mcsr"; 590 case dwarf_mir_mips: 591 return "mir"; 592 case dwarf_config5_mips: 593 return "config5"; 594 } 595 return nullptr; 596 } 597 598 bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind, 599 uint32_t reg_num, 600 RegisterInfo ®_info) { 601 if (reg_kind == eRegisterKindGeneric) { 602 switch (reg_num) { 603 case LLDB_REGNUM_GENERIC_PC: 604 reg_kind = eRegisterKindDWARF; 605 reg_num = dwarf_pc_mips; 606 break; 607 case LLDB_REGNUM_GENERIC_SP: 608 reg_kind = eRegisterKindDWARF; 609 reg_num = dwarf_sp_mips; 610 break; 611 case LLDB_REGNUM_GENERIC_FP: 612 reg_kind = eRegisterKindDWARF; 613 reg_num = dwarf_r30_mips; 614 break; 615 case LLDB_REGNUM_GENERIC_RA: 616 reg_kind = eRegisterKindDWARF; 617 reg_num = dwarf_ra_mips; 618 break; 619 case LLDB_REGNUM_GENERIC_FLAGS: 620 reg_kind = eRegisterKindDWARF; 621 reg_num = dwarf_sr_mips; 622 break; 623 default: 624 return false; 625 } 626 } 627 628 if (reg_kind == eRegisterKindDWARF) { 629 ::memset(®_info, 0, sizeof(RegisterInfo)); 630 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 631 632 if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || 633 reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || 634 reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) { 635 reg_info.byte_size = 4; 636 reg_info.format = eFormatHex; 637 reg_info.encoding = eEncodingUint; 638 } else if ((int)reg_num >= dwarf_zero_mips && 639 (int)reg_num <= dwarf_f31_mips) { 640 reg_info.byte_size = 4; 641 reg_info.format = eFormatHex; 642 reg_info.encoding = eEncodingUint; 643 } else if ((int)reg_num >= dwarf_w0_mips && 644 (int)reg_num <= dwarf_w31_mips) { 645 reg_info.byte_size = 16; 646 reg_info.format = eFormatVectorOfUInt8; 647 reg_info.encoding = eEncodingVector; 648 } else { 649 return false; 650 } 651 652 reg_info.name = GetRegisterName(reg_num, false); 653 reg_info.alt_name = GetRegisterName(reg_num, true); 654 reg_info.kinds[eRegisterKindDWARF] = reg_num; 655 656 switch (reg_num) { 657 case dwarf_r30_mips: 658 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 659 break; 660 case dwarf_ra_mips: 661 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 662 break; 663 case dwarf_sp_mips: 664 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 665 break; 666 case dwarf_pc_mips: 667 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 668 break; 669 case dwarf_sr_mips: 670 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 671 break; 672 default: 673 break; 674 } 675 return true; 676 } 677 return false; 678 } 679 680 EmulateInstructionMIPS::MipsOpcode * 681 EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) { 682 static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = { 683 //---------------------------------------------------------------------- 684 // Prologue/Epilogue instructions 685 //---------------------------------------------------------------------- 686 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, 687 "ADDIU rt, rs, immediate"}, 688 {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"}, 689 {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"}, 690 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"}, 691 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"}, 692 {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"}, 693 694 //---------------------------------------------------------------------- 695 // MicroMIPS Prologue/Epilogue instructions 696 //---------------------------------------------------------------------- 697 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, 698 "ADDIU immediate"}, 699 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, 700 "ADDIUS5 rd,immediate"}, 701 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"}, 702 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, 703 "SWM16 reglist,offset(sp)"}, 704 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, 705 "SWM32 reglist,offset(base)"}, 706 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, 707 "SWP rs1,offset(base)"}, 708 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"}, 709 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, 710 "LWM16 reglist,offset(sp)"}, 711 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, 712 "LWM32 reglist,offset(base)"}, 713 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, 714 "LWP rd,offset(base)"}, 715 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, 716 "JRADDIUSP immediate"}, 717 //---------------------------------------------------------------------- 718 719 // Load/Store instructions 720 //---------------------------------------------------------------------- 721 /* Following list of emulated instructions are required by implementation 722 of hardware watchpoint 723 for MIPS in lldb. As we just need the address accessed by instructions, 724 we have generalised 725 all these instructions in 2 functions depending on their addressing 726 modes */ 727 728 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm, 729 "LB rt, offset(base)"}, 730 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 731 "LBE rt, offset(base)"}, 732 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm, 733 "LBU rt, offset(base)"}, 734 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 735 "LBUE rt, offset(base)"}, 736 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 737 "LDC1 ft, offset(base)"}, 738 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 739 "LD rt, offset(base)"}, 740 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 741 "LDL rt, offset(base)"}, 742 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 743 "LDR rt, offset(base)"}, 744 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 745 "LLD rt, offset(base)"}, 746 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 747 "LDC2 rt, offset(base)"}, 748 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 749 "LDXC1 fd, index (base)"}, 750 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm, 751 "LH rt, offset(base)"}, 752 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 753 "LHE rt, offset(base)"}, 754 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm, 755 "LHU rt, offset(base)"}, 756 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 757 "LHUE rt, offset(base)"}, 758 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 759 "LL rt, offset(base)"}, 760 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 761 "LLE rt, offset(base)"}, 762 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 763 "LUXC1 fd, index (base)"}, 764 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm, 765 "LW rt, offset(base)"}, 766 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 767 "LWC1 ft, offset(base)"}, 768 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 769 "LWC2 rt, offset(base)"}, 770 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 771 "LWE rt, offset(base)"}, 772 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 773 "LWL rt, offset(base)"}, 774 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 775 "LWLE rt, offset(base)"}, 776 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 777 "LWR rt, offset(base)"}, 778 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 779 "LWRE rt, offset(base)"}, 780 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 781 "LWXC1 fd, index (base)"}, 782 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 783 "LLX rt, offset(base)"}, 784 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 785 "LLXE rt, offset(base)"}, 786 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 787 "LLDX rt, offset(base)"}, 788 789 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm, 790 "SB rt, offset(base)"}, 791 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 792 "SBE rt, offset(base)"}, 793 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm, 794 "SC rt, offset(base)"}, 795 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 796 "SCE rt, offset(base)"}, 797 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 798 "SCD rt, offset(base)"}, 799 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 800 "SD rt, offset(base)"}, 801 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 802 "SDL rt, offset(base)"}, 803 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 804 "SDR rt, offset(base)"}, 805 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 806 "SDC1 ft, offset(base)"}, 807 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 808 "SDC2 rt, offset(base)"}, 809 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 810 "SDXC1 fs, index(base)"}, 811 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm, 812 "SH rt, offset(base)"}, 813 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 814 "SHE rt, offset(base)"}, 815 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 816 "SUXC1 fs, index (base)"}, 817 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 818 "SWC1 ft, offset(base)"}, 819 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 820 "SWC2 rt, offset(base)"}, 821 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 822 "SWE rt, offset(base)"}, 823 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 824 "SWL rt, offset(base)"}, 825 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 826 "SWLE rt, offset(base)"}, 827 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 828 "SWR rt, offset(base)"}, 829 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 830 "SWRE rt, offset(base)"}, 831 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 832 "SWXC1 fs, index (base)"}, 833 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 834 "SCX rt, offset(base)"}, 835 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 836 "SCXE rt, offset(base)"}, 837 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 838 "SCDX rt, offset(base)"}, 839 840 //---------------------------------------------------------------------- 841 // MicroMIPS Load/Store instructions 842 //---------------------------------------------------------------------- 843 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 844 "LBU16 rt, decoded_offset(base)"}, 845 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 846 "LHU16 rt, left_shifted_offset(base)"}, 847 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 848 "LW16 rt, left_shifted_offset(base)"}, 849 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 850 "LWGP rt, left_shifted_offset(gp)"}, 851 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 852 "SH16 rt, left_shifted_offset(base)"}, 853 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 854 "SW16 rt, left_shifted_offset(base)"}, 855 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 856 "SWSP rt, left_shifted_offset(base)"}, 857 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 858 "SB16 rt, offset(base)"}, 859 860 //---------------------------------------------------------------------- 861 // Branch instructions 862 //---------------------------------------------------------------------- 863 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"}, 864 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"}, 865 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"}, 866 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"}, 867 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 868 "BGEZALL rt,offset"}, 869 {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"}, 870 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 871 "BGEZAL rs,offset"}, 872 {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"}, 873 {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"}, 874 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"}, 875 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 876 "BLEZALC rs,offset"}, 877 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 878 "BGEZALC rs,offset"}, 879 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 880 "BLTZALC rs,offset"}, 881 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 882 "BGTZALC rs,offset"}, 883 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 884 "BEQZALC rs,offset"}, 885 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 886 "BNEZALC rs,offset"}, 887 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 888 "BEQC rs,rt,offset"}, 889 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 890 "BNEC rs,rt,offset"}, 891 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 892 "BLTC rs,rt,offset"}, 893 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 894 "BGEC rs,rt,offset"}, 895 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 896 "BLTUC rs,rt,offset"}, 897 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 898 "BGEUC rs,rt,offset"}, 899 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"}, 900 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"}, 901 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"}, 902 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"}, 903 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"}, 904 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"}, 905 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"}, 906 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"}, 907 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"}, 908 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"}, 909 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"}, 910 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"}, 911 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 912 "BLTZAL rt,offset"}, 913 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 914 "BLTZALL rt,offset"}, 915 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"}, 916 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 917 "BOVC rs,rt,offset"}, 918 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 919 "BNVC rs,rt,offset"}, 920 {"J", &EmulateInstructionMIPS::Emulate_J, "J target"}, 921 {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"}, 922 {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"}, 923 {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"}, 924 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"}, 925 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"}, 926 {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"}, 927 {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"}, 928 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"}, 929 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"}, 930 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"}, 931 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"}, 932 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"}, 933 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"}, 934 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"}, 935 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch, 936 "BC1ANY2F cc, offset"}, 937 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch, 938 "BC1ANY2T cc, offset"}, 939 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch, 940 "BC1ANY4F cc, offset"}, 941 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch, 942 "BC1ANY4T cc, offset"}, 943 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"}, 944 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"}, 945 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"}, 946 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"}, 947 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"}, 948 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"}, 949 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"}, 950 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"}, 951 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"}, 952 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"}, 953 954 //---------------------------------------------------------------------- 955 // MicroMIPS Branch instructions 956 //---------------------------------------------------------------------- 957 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"}, 958 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 959 "BEQZ16 rs, offset"}, 960 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 961 "BNEZ16 rs, offset"}, 962 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 963 "BEQZC rs, offset"}, 964 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 965 "BNEZC rs, offset"}, 966 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 967 "BGEZALS rs, offset"}, 968 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 969 "BLTZALS rs, offset"}, 970 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"}, 971 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"}, 972 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"}, 973 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"}, 974 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"}, 975 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"}, 976 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"}, 977 }; 978 979 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); 980 981 for (size_t i = 0; i < k_num_mips_opcodes; ++i) { 982 if (!strcasecmp(g_opcodes[i].op_name, op_name)) 983 return &g_opcodes[i]; 984 } 985 986 return NULL; 987 } 988 989 uint32_t 990 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data, 991 uint64_t inst_addr) { 992 uint64_t next_inst_size = 0; 993 llvm::MCInst mc_insn; 994 llvm::MCDisassembler::DecodeStatus decode_status; 995 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); 996 997 if (m_use_alt_disaasm) 998 decode_status = 999 m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, 1000 inst_addr, llvm::nulls(), llvm::nulls()); 1001 else 1002 decode_status = 1003 m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr, 1004 llvm::nulls(), llvm::nulls()); 1005 1006 if (decode_status != llvm::MCDisassembler::Success) 1007 return false; 1008 1009 return m_insn_info->get(mc_insn.getOpcode()).getSize(); 1010 } 1011 1012 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode, 1013 const Address &inst_addr, 1014 Target *target) { 1015 m_use_alt_disaasm = false; 1016 1017 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 1018 if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) { 1019 Status error; 1020 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1021 1022 /* 1023 * The address belongs to microMIPS function. To find the size of 1024 * next instruction use microMIPS disassembler. 1025 */ 1026 m_use_alt_disaasm = true; 1027 1028 uint32_t current_inst_size = insn_opcode.GetByteSize(); 1029 uint8_t buf[sizeof(uint32_t)]; 1030 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size; 1031 Address next_addr(next_inst_addr); 1032 1033 const size_t bytes_read = 1034 target->ReadMemory(next_addr, /* Address of next instruction */ 1035 true, /* prefer_file_cache */ 1036 buf, sizeof(uint32_t), error, &load_addr); 1037 1038 if (bytes_read == 0) 1039 return true; 1040 1041 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(), 1042 GetAddressByteSize()); 1043 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr); 1044 return true; 1045 } else { 1046 /* 1047 * If the address class is not eAddressClassCodeAlternateISA then 1048 * the function is not microMIPS. In this case instruction size is 1049 * always 4 bytes. 1050 */ 1051 m_next_inst_size = 4; 1052 return true; 1053 } 1054 } 1055 return false; 1056 } 1057 1058 bool EmulateInstructionMIPS::ReadInstruction() { 1059 bool success = false; 1060 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 1061 LLDB_INVALID_ADDRESS, &success); 1062 if (success) { 1063 Context read_inst_context; 1064 read_inst_context.type = eContextReadOpcode; 1065 read_inst_context.SetNoArgs(); 1066 m_opcode.SetOpcode32( 1067 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success), 1068 GetByteOrder()); 1069 } 1070 if (!success) 1071 m_addr = LLDB_INVALID_ADDRESS; 1072 return success; 1073 } 1074 1075 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) { 1076 bool success = false; 1077 llvm::MCInst mc_insn; 1078 uint64_t insn_size; 1079 DataExtractor data; 1080 1081 /* Keep the complexity of the decode logic with the llvm::MCDisassembler 1082 * class. */ 1083 if (m_opcode.GetData(data)) { 1084 llvm::MCDisassembler::DecodeStatus decode_status; 1085 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); 1086 if (m_use_alt_disaasm) 1087 decode_status = m_alt_disasm->getInstruction( 1088 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); 1089 else 1090 decode_status = m_disasm->getInstruction( 1091 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); 1092 1093 if (decode_status != llvm::MCDisassembler::Success) 1094 return false; 1095 } 1096 1097 /* 1098 * mc_insn.getOpcode() returns decoded opcode. However to make use 1099 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". 1100 */ 1101 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data(); 1102 1103 if (op_name == NULL) 1104 return false; 1105 1106 /* 1107 * Decoding has been done already. Just get the call-back function 1108 * and emulate the instruction. 1109 */ 1110 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name); 1111 1112 if (opcode_data == NULL) 1113 return false; 1114 1115 uint64_t old_pc = 0, new_pc = 0; 1116 const bool auto_advance_pc = 1117 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 1118 1119 if (auto_advance_pc) { 1120 old_pc = 1121 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1122 if (!success) 1123 return false; 1124 } 1125 1126 /* emulate instruction */ 1127 success = (this->*opcode_data->callback)(mc_insn); 1128 if (!success) 1129 return false; 1130 1131 if (auto_advance_pc) { 1132 new_pc = 1133 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1134 if (!success) 1135 return false; 1136 1137 /* If we haven't changed the PC, change it here */ 1138 if (old_pc == new_pc) { 1139 new_pc += 4; 1140 Context context; 1141 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1142 new_pc)) 1143 return false; 1144 } 1145 } 1146 1147 return true; 1148 } 1149 1150 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind( 1151 UnwindPlan &unwind_plan) { 1152 unwind_plan.Clear(); 1153 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1154 1155 UnwindPlan::RowSP row(new UnwindPlan::Row); 1156 const bool can_replace = false; 1157 1158 // Our previous Call Frame Address is the stack pointer 1159 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0); 1160 1161 // Our previous PC is in the RA 1162 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace); 1163 1164 unwind_plan.AppendRow(row); 1165 1166 // All other registers are the same. 1167 unwind_plan.SetSourceName("EmulateInstructionMIPS"); 1168 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1169 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 1170 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips); 1171 1172 return true; 1173 } 1174 1175 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) { 1176 switch (regnum) { 1177 case dwarf_r16_mips: 1178 case dwarf_r17_mips: 1179 case dwarf_r18_mips: 1180 case dwarf_r19_mips: 1181 case dwarf_r20_mips: 1182 case dwarf_r21_mips: 1183 case dwarf_r22_mips: 1184 case dwarf_r23_mips: 1185 case dwarf_gp_mips: 1186 case dwarf_sp_mips: 1187 case dwarf_r30_mips: 1188 case dwarf_ra_mips: 1189 return true; 1190 default: 1191 return false; 1192 } 1193 return false; 1194 } 1195 1196 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) { 1197 // ADDIU rt, rs, immediate 1198 // GPR[rt] <- GPR[rs] + sign_extend(immediate) 1199 1200 uint8_t dst, src; 1201 bool success = false; 1202 const uint32_t imm16 = insn.getOperand(2).getImm(); 1203 int64_t imm = SignedBits(imm16, 15, 0); 1204 1205 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1206 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1207 1208 // If immediate value is greater then 2^16 - 1 then clang generate 1209 // LUI, ADDIU, SUBU instructions in prolog. 1210 // Example 1211 // lui $1, 0x2 1212 // addiu $1, $1, -0x5920 1213 // subu $sp, $sp, $1 1214 // In this case, ADDIU dst and src will be same and not equal to sp 1215 if (dst == src) { 1216 Context context; 1217 1218 /* read <src> register */ 1219 const int64_t src_opd_val = ReadRegisterUnsigned( 1220 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 1221 if (!success) 1222 return false; 1223 1224 /* Check if this is daddiu sp, sp, imm16 */ 1225 if (dst == dwarf_sp_mips) { 1226 uint64_t result = src_opd_val + imm; 1227 RegisterInfo reg_info_sp; 1228 1229 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1230 context.SetRegisterPlusOffset(reg_info_sp, imm); 1231 1232 /* We are allocating bytes on stack */ 1233 context.type = eContextAdjustStackPointer; 1234 1235 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1236 return true; 1237 } 1238 1239 imm += src_opd_val; 1240 context.SetImmediateSigned(imm); 1241 context.type = eContextImmediate; 1242 1243 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1244 dwarf_zero_mips + dst, imm)) 1245 return false; 1246 } 1247 1248 return true; 1249 } 1250 1251 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) { 1252 bool success = false; 1253 uint32_t imm16 = insn.getOperand(2).getImm(); 1254 uint32_t imm = SignedBits(imm16, 15, 0); 1255 uint32_t src, base; 1256 int32_t address; 1257 Context bad_vaddr_context; 1258 1259 RegisterInfo reg_info_base; 1260 1261 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1262 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1263 1264 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1265 reg_info_base)) 1266 return false; 1267 1268 /* read base register */ 1269 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1270 dwarf_zero_mips + base, 0, &success); 1271 if (!success) 1272 return false; 1273 1274 /* destination address */ 1275 address = address + imm; 1276 1277 /* Set the bad_vaddr register with base address used in the instruction */ 1278 bad_vaddr_context.type = eContextInvalid; 1279 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1280 address); 1281 1282 /* We look for sp based non-volatile register stores */ 1283 if (nonvolatile_reg_p(src)) { 1284 1285 RegisterInfo reg_info_src; 1286 1287 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1288 reg_info_src)) 1289 return false; 1290 1291 Context context; 1292 RegisterValue data_src; 1293 context.type = eContextPushRegisterOnStack; 1294 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1295 1296 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1297 Status error; 1298 1299 if (!ReadRegister(®_info_base, data_src)) 1300 return false; 1301 1302 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1303 eByteOrderLittle, error) == 0) 1304 return false; 1305 1306 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) 1307 return false; 1308 1309 return true; 1310 } 1311 1312 return false; 1313 } 1314 1315 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) { 1316 bool success = false; 1317 uint32_t src, base; 1318 int32_t imm, address; 1319 Context bad_vaddr_context; 1320 1321 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1322 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1323 imm = insn.getOperand(2).getImm(); 1324 1325 RegisterInfo reg_info_base; 1326 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1327 reg_info_base)) 1328 return false; 1329 1330 /* read base register */ 1331 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1332 dwarf_zero_mips + base, 0, &success); 1333 if (!success) 1334 return false; 1335 1336 /* destination address */ 1337 address = address + imm; 1338 1339 /* Set the bad_vaddr register with base address used in the instruction */ 1340 bad_vaddr_context.type = eContextInvalid; 1341 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1342 address); 1343 1344 if (nonvolatile_reg_p(src)) { 1345 RegisterValue data_src; 1346 RegisterInfo reg_info_src; 1347 1348 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1349 reg_info_src)) 1350 return false; 1351 1352 Context context; 1353 context.type = eContextPopRegisterOffStack; 1354 context.SetAddress(address); 1355 1356 if (!WriteRegister(context, ®_info_src, data_src)) 1357 return false; 1358 1359 return true; 1360 } 1361 1362 return false; 1363 } 1364 1365 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) { 1366 // SUBU sp, <src>, <rt> 1367 // ADDU sp, <src>, <rt> 1368 // ADDU dst, sp, <rt> 1369 1370 bool success = false; 1371 uint64_t result; 1372 uint8_t src, dst, rt; 1373 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1374 1375 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1376 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1377 1378 /* Check if sp is destination register */ 1379 if (dst == dwarf_sp_mips) { 1380 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1381 1382 /* read <src> register */ 1383 uint64_t src_opd_val = ReadRegisterUnsigned( 1384 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 1385 if (!success) 1386 return false; 1387 1388 /* read <rt > register */ 1389 uint64_t rt_opd_val = ReadRegisterUnsigned( 1390 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 1391 if (!success) 1392 return false; 1393 1394 if (!strcasecmp(op_name, "SUBU")) 1395 result = src_opd_val - rt_opd_val; 1396 else 1397 result = src_opd_val + rt_opd_val; 1398 1399 Context context; 1400 RegisterInfo reg_info_sp; 1401 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1402 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val); 1403 1404 /* We are allocating bytes on stack */ 1405 context.type = eContextAdjustStackPointer; 1406 1407 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1408 1409 return true; 1410 } else if (src == dwarf_sp_mips) { 1411 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1412 1413 /* read <src> register */ 1414 uint64_t src_opd_val = ReadRegisterUnsigned( 1415 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 1416 if (!success) 1417 return false; 1418 1419 /* read <rt> register */ 1420 uint64_t rt_opd_val = ReadRegisterUnsigned( 1421 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 1422 if (!success) 1423 return false; 1424 1425 Context context; 1426 1427 if (!strcasecmp(op_name, "SUBU")) 1428 result = src_opd_val - rt_opd_val; 1429 else 1430 result = src_opd_val + rt_opd_val; 1431 1432 context.SetImmediateSigned(result); 1433 context.type = eContextImmediate; 1434 1435 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1436 dwarf_zero_mips + dst, result)) 1437 return false; 1438 } 1439 1440 return true; 1441 } 1442 1443 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) { 1444 // LUI rt, immediate 1445 // GPR[rt] <- sign_extend(immediate << 16) 1446 1447 const uint32_t imm32 = insn.getOperand(1).getImm() << 16; 1448 int64_t imm = SignedBits(imm32, 31, 0); 1449 uint8_t rt; 1450 Context context; 1451 1452 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1453 context.SetImmediateSigned(imm); 1454 context.type = eContextImmediate; 1455 1456 if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 1457 imm)) 1458 return true; 1459 1460 return false; 1461 } 1462 1463 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) { 1464 bool success = false; 1465 const uint32_t imm9 = insn.getOperand(0).getImm(); 1466 uint64_t result; 1467 1468 // This instruction operates implicitly on stack pointer, so read <sp> 1469 // register. 1470 uint64_t src_opd_val = 1471 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1472 if (!success) 1473 return false; 1474 1475 result = src_opd_val + imm9; 1476 1477 Context context; 1478 RegisterInfo reg_info_sp; 1479 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1480 context.SetRegisterPlusOffset(reg_info_sp, imm9); 1481 1482 // We are adjusting the stack. 1483 context.type = eContextAdjustStackPointer; 1484 1485 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1486 return true; 1487 } 1488 1489 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) { 1490 bool success = false; 1491 uint32_t base; 1492 const uint32_t imm4 = insn.getOperand(2).getImm(); 1493 uint64_t result; 1494 1495 // The source and destination register is same for this instruction. 1496 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1497 1498 // We are looking for stack adjustment only 1499 if (base == dwarf_sp_mips) { 1500 // Read stack pointer register 1501 uint64_t src_opd_val = ReadRegisterUnsigned( 1502 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1503 if (!success) 1504 return false; 1505 1506 result = src_opd_val + imm4; 1507 1508 Context context; 1509 RegisterInfo reg_info_sp; 1510 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1511 context.SetRegisterPlusOffset(reg_info_sp, imm4); 1512 1513 // We are adjusting the stack. 1514 context.type = eContextAdjustStackPointer; 1515 1516 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1517 } 1518 1519 return true; 1520 } 1521 1522 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) { 1523 bool success = false; 1524 uint32_t imm5 = insn.getOperand(2).getImm(); 1525 uint32_t src, base; 1526 Context bad_vaddr_context; 1527 uint32_t address; 1528 1529 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1530 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1531 1532 RegisterInfo reg_info_base; 1533 1534 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1535 reg_info_base)) 1536 return false; 1537 1538 // read base register 1539 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, 1540 &success); 1541 if (!success) 1542 return false; 1543 1544 // destination address 1545 address = address + imm5; 1546 1547 // We use bad_vaddr_context to store base address which is used by H/W 1548 // watchpoint 1549 // Set the bad_vaddr register with base address used in the instruction 1550 bad_vaddr_context.type = eContextInvalid; 1551 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1552 address); 1553 1554 // We look for sp based non-volatile register stores. 1555 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { 1556 RegisterInfo reg_info_src = {}; 1557 Context context; 1558 RegisterValue data_src; 1559 context.type = eContextPushRegisterOnStack; 1560 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1561 1562 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1563 Status error; 1564 1565 if (!ReadRegister(®_info_base, data_src)) 1566 return false; 1567 1568 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1569 eByteOrderLittle, error) == 0) 1570 return false; 1571 1572 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) 1573 return false; 1574 1575 return true; 1576 } 1577 1578 return false; 1579 } 1580 1581 /* Emulate SWM16,SWM32 and SWP instruction. 1582 1583 SWM16 always has stack pointer as a base register (but it is still available 1584 in MCInst as an operand). 1585 SWM32 and SWP can have base register other than stack pointer. 1586 */ 1587 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) { 1588 bool success = false; 1589 uint32_t src, base; 1590 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on 1591 // no of regs to store. 1592 1593 // Base register is second last operand of the instruction. 1594 base = 1595 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 1596 1597 // We are looking for sp based stores so if base is not a stack pointer then 1598 // don't proceed. 1599 if (base != dwarf_sp_mips) 1600 return false; 1601 1602 // offset is always the last operand. 1603 uint32_t offset = insn.getOperand(num_operands - 1).getImm(); 1604 1605 RegisterInfo reg_info_base; 1606 RegisterInfo reg_info_src; 1607 1608 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1609 reg_info_base)) 1610 return false; 1611 1612 // read SP 1613 uint32_t base_address = ReadRegisterUnsigned( 1614 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1615 if (!success) 1616 return false; 1617 1618 // Resulting base addrss 1619 base_address = base_address + offset; 1620 1621 // Total no of registers to be stored are num_operands-2. 1622 for (uint32_t i = 0; i < num_operands - 2; i++) { 1623 // Get the register number to be stored. 1624 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); 1625 1626 /* 1627 Record only non-volatile stores. 1628 This check is required for SWP instruction because source operand could 1629 be any register. 1630 SWM16 and SWM32 instruction always has saved registers as source 1631 operands. 1632 */ 1633 if (!nonvolatile_reg_p(src)) 1634 return false; 1635 1636 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1637 reg_info_src)) 1638 return false; 1639 1640 Context context; 1641 RegisterValue data_src; 1642 context.type = eContextPushRegisterOnStack; 1643 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1644 1645 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1646 Status error; 1647 1648 if (!ReadRegister(®_info_base, data_src)) 1649 return false; 1650 1651 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1652 eByteOrderLittle, error) == 0) 1653 return false; 1654 1655 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size)) 1656 return false; 1657 1658 // Stack address for next register 1659 base_address = base_address + reg_info_src.byte_size; 1660 } 1661 return true; 1662 } 1663 1664 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) { 1665 bool success = false; 1666 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1667 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1668 uint32_t imm5 = insn.getOperand(2).getImm(); 1669 Context bad_vaddr_context; 1670 1671 RegisterInfo reg_info_base; 1672 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1673 reg_info_base)) 1674 return false; 1675 1676 // read base register 1677 uint32_t base_address = ReadRegisterUnsigned( 1678 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1679 if (!success) 1680 return false; 1681 1682 base_address = base_address + imm5; 1683 1684 // We use bad_vaddr_context to store base address which is used by H/W 1685 // watchpoint 1686 // Set the bad_vaddr register with base address used in the instruction 1687 bad_vaddr_context.type = eContextInvalid; 1688 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1689 base_address); 1690 1691 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { 1692 RegisterValue data_src; 1693 RegisterInfo reg_info_src; 1694 1695 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1696 reg_info_src)) 1697 return false; 1698 1699 Context context; 1700 context.type = eContextPopRegisterOffStack; 1701 context.SetAddress(base_address); 1702 1703 if (!WriteRegister(context, ®_info_src, data_src)) 1704 return false; 1705 1706 return true; 1707 } 1708 1709 return false; 1710 } 1711 1712 /* Emulate LWM16, LWM32 and LWP instructions. 1713 1714 LWM16 always has stack pointer as a base register (but it is still available 1715 in MCInst as an operand). 1716 LWM32 and LWP can have base register other than stack pointer. 1717 */ 1718 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) { 1719 bool success = false; 1720 uint32_t dst, base; 1721 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on 1722 // no of regs to store. 1723 uint32_t imm = insn.getOperand(num_operands - 1) 1724 .getImm(); // imm is the last operand in the instruction. 1725 1726 // Base register is second last operand of the instruction. 1727 base = 1728 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 1729 1730 // We are looking for sp based loads so if base is not a stack pointer then 1731 // don't proceed. 1732 if (base != dwarf_sp_mips) 1733 return false; 1734 1735 uint32_t base_address = ReadRegisterUnsigned( 1736 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1737 if (!success) 1738 return false; 1739 1740 base_address = base_address + imm; 1741 1742 RegisterValue data_dst; 1743 RegisterInfo reg_info_dst; 1744 1745 // Total no of registers to be re-stored are num_operands-2. 1746 for (uint32_t i = 0; i < num_operands - 2; i++) { 1747 // Get the register number to be re-stored. 1748 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); 1749 1750 /* 1751 Record only non-volatile loads. 1752 This check is required for LWP instruction because destination operand 1753 could be any register. 1754 LWM16 and LWM32 instruction always has saved registers as destination 1755 operands. 1756 */ 1757 if (!nonvolatile_reg_p(dst)) 1758 return false; 1759 1760 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst, 1761 reg_info_dst)) 1762 return false; 1763 1764 Context context; 1765 context.type = eContextPopRegisterOffStack; 1766 context.SetAddress(base_address + (i * 4)); 1767 1768 if (!WriteRegister(context, ®_info_dst, data_dst)) 1769 return false; 1770 } 1771 1772 return true; 1773 } 1774 1775 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) { 1776 bool success = false; 1777 int32_t imm5 = insn.getOperand(0).getImm(); 1778 1779 /* JRADDIUSP immediate 1780 * PC <- RA 1781 * SP <- SP + zero_extend(Immediate << 2) 1782 */ 1783 1784 // This instruction operates implicitly on stack pointer, so read <sp> 1785 // register. 1786 int32_t src_opd_val = 1787 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1788 if (!success) 1789 return false; 1790 1791 int32_t ra_val = 1792 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success); 1793 if (!success) 1794 return false; 1795 1796 int32_t result = src_opd_val + imm5; 1797 1798 Context context; 1799 1800 // Update the PC 1801 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1802 ra_val)) 1803 return false; 1804 1805 RegisterInfo reg_info_sp; 1806 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1807 context.SetRegisterPlusOffset(reg_info_sp, imm5); 1808 1809 // We are adjusting stack 1810 context.type = eContextAdjustStackPointer; 1811 1812 // update SP 1813 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, 1814 result)) 1815 return false; 1816 1817 return true; 1818 } 1819 1820 static int IsAdd64bitOverflow(int32_t a, int32_t b) { 1821 int32_t r = (uint32_t)a + (uint32_t)b; 1822 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0); 1823 } 1824 1825 /* 1826 Emulate below MIPS branch instructions. 1827 BEQ, BNE : Branch on condition 1828 BEQL, BNEL : Branch likely 1829 */ 1830 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { 1831 bool success = false; 1832 uint32_t rs, rt; 1833 int32_t offset, pc, target = 0, rs_val, rt_val; 1834 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1835 1836 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1837 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1838 offset = insn.getOperand(2).getImm(); 1839 1840 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1841 if (!success) 1842 return false; 1843 1844 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1845 dwarf_zero_mips + rs, 0, &success); 1846 if (!success) 1847 return false; 1848 1849 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1850 dwarf_zero_mips + rt, 0, &success); 1851 if (!success) 1852 return false; 1853 1854 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) { 1855 if (rs_val == rt_val) 1856 target = pc + offset; 1857 else 1858 target = pc + 8; 1859 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) { 1860 if (rs_val != rt_val) 1861 target = pc + offset; 1862 else 1863 target = pc + 8; 1864 } 1865 1866 Context context; 1867 context.type = eContextRelativeBranchImmediate; 1868 context.SetImmediate(offset); 1869 1870 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1871 target)) 1872 return false; 1873 1874 return true; 1875 } 1876 1877 /* 1878 Emulate below MIPS branch instructions. 1879 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch 1880 instructions with no delay slot 1881 */ 1882 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { 1883 bool success = false; 1884 uint32_t rs, rt; 1885 int32_t offset, pc, target = 0, rs_val, rt_val; 1886 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1887 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1888 1889 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1890 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1891 offset = insn.getOperand(2).getImm(); 1892 1893 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1894 if (!success) 1895 return false; 1896 1897 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1898 dwarf_zero_mips + rs, 0, &success); 1899 if (!success) 1900 return false; 1901 1902 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1903 dwarf_zero_mips + rt, 0, &success); 1904 if (!success) 1905 return false; 1906 1907 if (!strcasecmp(op_name, "BEQC")) { 1908 if (rs_val == rt_val) 1909 target = pc + offset; 1910 else 1911 target = pc + 4; 1912 } else if (!strcasecmp(op_name, "BNEC")) { 1913 if (rs_val != rt_val) 1914 target = pc + offset; 1915 else 1916 target = pc + 4; 1917 } else if (!strcasecmp(op_name, "BLTC")) { 1918 if (rs_val < rt_val) 1919 target = pc + offset; 1920 else 1921 target = pc + 4; 1922 } else if (!strcasecmp(op_name, "BGEC")) { 1923 if (rs_val >= rt_val) 1924 target = pc + offset; 1925 else 1926 target = pc + 4; 1927 } else if (!strcasecmp(op_name, "BLTUC")) { 1928 if (rs_val < rt_val) 1929 target = pc + offset; 1930 else 1931 target = pc + 4; 1932 } else if (!strcasecmp(op_name, "BGEUC")) { 1933 if ((uint32_t)rs_val >= (uint32_t)rt_val) 1934 target = pc + offset; 1935 else 1936 target = pc + 4; 1937 } else if (!strcasecmp(op_name, "BOVC")) { 1938 if (IsAdd64bitOverflow(rs_val, rt_val)) 1939 target = pc + offset; 1940 else 1941 target = pc + 4; 1942 } else if (!strcasecmp(op_name, "BNVC")) { 1943 if (!IsAdd64bitOverflow(rs_val, rt_val)) 1944 target = pc + offset; 1945 else 1946 target = pc + 4; 1947 } 1948 1949 Context context; 1950 context.type = eContextRelativeBranchImmediate; 1951 context.SetImmediate(current_inst_size + offset); 1952 1953 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1954 target)) 1955 return false; 1956 1957 return true; 1958 } 1959 1960 /* 1961 Emulate below MIPS conditional branch and link instructions. 1962 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches 1963 */ 1964 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) { 1965 bool success = false; 1966 uint32_t rs; 1967 int32_t offset, pc, target = 0; 1968 int32_t rs_val; 1969 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1970 1971 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1972 offset = insn.getOperand(1).getImm(); 1973 1974 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1975 if (!success) 1976 return false; 1977 1978 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1979 dwarf_zero_mips + rs, 0, &success); 1980 if (!success) 1981 return false; 1982 1983 if (!strcasecmp(op_name, "BLEZALC")) { 1984 if (rs_val <= 0) 1985 target = pc + offset; 1986 else 1987 target = pc + 4; 1988 } else if (!strcasecmp(op_name, "BGEZALC")) { 1989 if (rs_val >= 0) 1990 target = pc + offset; 1991 else 1992 target = pc + 4; 1993 } else if (!strcasecmp(op_name, "BLTZALC")) { 1994 if (rs_val < 0) 1995 target = pc + offset; 1996 else 1997 target = pc + 4; 1998 } else if (!strcasecmp(op_name, "BGTZALC")) { 1999 if (rs_val > 0) 2000 target = pc + offset; 2001 else 2002 target = pc + 4; 2003 } else if (!strcasecmp(op_name, "BEQZALC")) { 2004 if (rs_val == 0) 2005 target = pc + offset; 2006 else 2007 target = pc + 4; 2008 } else if (!strcasecmp(op_name, "BNEZALC")) { 2009 if (rs_val != 0) 2010 target = pc + offset; 2011 else 2012 target = pc + 4; 2013 } 2014 2015 Context context; 2016 2017 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2018 target)) 2019 return false; 2020 2021 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2022 pc + 4)) 2023 return false; 2024 2025 return true; 2026 } 2027 2028 /* 2029 Emulate below MIPS Non-Compact conditional branch and link instructions. 2030 BLTZAL, BGEZAL : 2031 BLTZALL, BGEZALL : Branch likely 2032 */ 2033 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) { 2034 bool success = false; 2035 uint32_t rs; 2036 int32_t offset, pc, target = 0; 2037 int32_t rs_val; 2038 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2039 2040 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2041 offset = insn.getOperand(1).getImm(); 2042 2043 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2044 if (!success) 2045 return false; 2046 2047 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2048 dwarf_zero_mips + rs, 0, &success); 2049 if (!success) 2050 return false; 2051 2052 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) { 2053 if ((int32_t)rs_val < 0) 2054 target = pc + offset; 2055 else 2056 target = pc + 8; 2057 } else if (!strcasecmp(op_name, "BGEZAL") || 2058 !strcasecmp(op_name, "BGEZALL")) { 2059 if ((int32_t)rs_val >= 0) 2060 target = pc + offset; 2061 else 2062 target = pc + 8; 2063 } 2064 2065 Context context; 2066 2067 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2068 target)) 2069 return false; 2070 2071 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2072 pc + 8)) 2073 return false; 2074 2075 return true; 2076 } 2077 2078 /* 2079 Emulate below MIPS branch instructions. 2080 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely 2081 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches 2082 */ 2083 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { 2084 bool success = false; 2085 uint32_t rs; 2086 int32_t offset, pc, target = 0; 2087 int32_t rs_val; 2088 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2089 2090 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2091 offset = insn.getOperand(1).getImm(); 2092 2093 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2094 if (!success) 2095 return false; 2096 2097 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2098 dwarf_zero_mips + rs, 0, &success); 2099 if (!success) 2100 return false; 2101 2102 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) { 2103 if (rs_val < 0) 2104 target = pc + offset; 2105 else 2106 target = pc + 8; 2107 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) { 2108 if (rs_val >= 0) 2109 target = pc + offset; 2110 else 2111 target = pc + 8; 2112 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) { 2113 if (rs_val > 0) 2114 target = pc + offset; 2115 else 2116 target = pc + 8; 2117 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) { 2118 if (rs_val <= 0) 2119 target = pc + offset; 2120 else 2121 target = pc + 8; 2122 } 2123 2124 Context context; 2125 context.type = eContextRelativeBranchImmediate; 2126 context.SetImmediate(offset); 2127 2128 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2129 target)) 2130 return false; 2131 2132 return true; 2133 } 2134 2135 /* 2136 Emulate below MIPS branch instructions. 2137 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches 2138 */ 2139 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { 2140 bool success = false; 2141 uint32_t rs; 2142 int32_t offset, pc, target = 0; 2143 int32_t rs_val; 2144 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2145 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2146 2147 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2148 offset = insn.getOperand(1).getImm(); 2149 2150 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2151 if (!success) 2152 return false; 2153 2154 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2155 dwarf_zero_mips + rs, 0, &success); 2156 if (!success) 2157 return false; 2158 2159 if (!strcasecmp(op_name, "BLTZC")) { 2160 if (rs_val < 0) 2161 target = pc + offset; 2162 else 2163 target = pc + 4; 2164 } else if (!strcasecmp(op_name, "BLEZC")) { 2165 if (rs_val <= 0) 2166 target = pc + offset; 2167 else 2168 target = pc + 4; 2169 } else if (!strcasecmp(op_name, "BGEZC")) { 2170 if (rs_val >= 0) 2171 target = pc + offset; 2172 else 2173 target = pc + 4; 2174 } else if (!strcasecmp(op_name, "BGTZC")) { 2175 if (rs_val > 0) 2176 target = pc + offset; 2177 else 2178 target = pc + 4; 2179 } else if (!strcasecmp(op_name, "BEQZC")) { 2180 if (rs_val == 0) 2181 target = pc + offset; 2182 else 2183 target = pc + 4; 2184 } else if (!strcasecmp(op_name, "BNEZC")) { 2185 if (rs_val != 0) 2186 target = pc + offset; 2187 else 2188 target = pc + 4; 2189 } 2190 2191 Context context; 2192 context.type = eContextRelativeBranchImmediate; 2193 context.SetImmediate(current_inst_size + offset); 2194 2195 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2196 target)) 2197 return false; 2198 2199 return true; 2200 } 2201 2202 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) { 2203 bool success = false; 2204 int32_t offset, pc, target; 2205 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2206 2207 offset = insn.getOperand(0).getImm(); 2208 2209 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2210 if (!success) 2211 return false; 2212 2213 // unconditional branch 2214 target = pc + offset; 2215 2216 Context context; 2217 context.type = eContextRelativeBranchImmediate; 2218 context.SetImmediate(current_inst_size + offset); 2219 2220 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2221 target)) 2222 return false; 2223 2224 return true; 2225 } 2226 2227 /* 2228 BEQZC, BNEZC are 32 bit compact instructions without a delay slot. 2229 BEQZ16, BNEZ16 are 16 bit instructions with delay slot. 2230 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot. 2231 */ 2232 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { 2233 bool success = false; 2234 int32_t target = 0; 2235 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2236 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2237 bool update_ra = false; 2238 uint32_t ra_offset = 0; 2239 2240 /* 2241 * BEQZ16 rs, offset 2242 * condition <- (GPR[rs] = 0) 2243 * if condition then 2244 * PC = PC + sign_ext (offset || 0) 2245 * 2246 * BNEZ16 rs, offset 2247 * condition <- (GPR[rs] != 0) 2248 * if condition then 2249 * PC = PC + sign_ext (offset || 0) 2250 * 2251 * BEQZC rs, offset (compact instruction: No delay slot) 2252 * condition <- (GPR[rs] == 0) 2253 * if condition then 2254 * PC = PC + 4 + sign_ext (offset || 0) 2255 */ 2256 2257 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2258 int32_t offset = insn.getOperand(1).getImm(); 2259 2260 int32_t pc = 2261 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2262 if (!success) 2263 return false; 2264 2265 int32_t rs_val = (int32_t)ReadRegisterUnsigned( 2266 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 2267 if (!success) 2268 return false; 2269 2270 if (!strcasecmp(op_name, "BEQZ16_MM")) { 2271 if (rs_val == 0) 2272 target = pc + offset; 2273 else 2274 target = pc + current_inst_size + 2275 m_next_inst_size; // Skip delay slot instruction. 2276 } else if (!strcasecmp(op_name, "BNEZ16_MM")) { 2277 if (rs_val != 0) 2278 target = pc + offset; 2279 else 2280 target = pc + current_inst_size + 2281 m_next_inst_size; // Skip delay slot instruction. 2282 } else if (!strcasecmp(op_name, "BEQZC_MM")) { 2283 if (rs_val == 0) 2284 target = pc + 4 + offset; 2285 else 2286 target = 2287 pc + 2288 4; // 32 bit instruction and does not have delay slot instruction. 2289 } else if (!strcasecmp(op_name, "BNEZC_MM")) { 2290 if (rs_val != 0) 2291 target = pc + 4 + offset; 2292 else 2293 target = 2294 pc + 2295 4; // 32 bit instruction and does not have delay slot instruction. 2296 } else if (!strcasecmp(op_name, "BGEZALS_MM")) { 2297 if (rs_val >= 0) 2298 target = pc + offset; 2299 else 2300 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 2301 2302 update_ra = true; 2303 ra_offset = 6; 2304 } else if (!strcasecmp(op_name, "BLTZALS_MM")) { 2305 if (rs_val >= 0) 2306 target = pc + offset; 2307 else 2308 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 2309 2310 update_ra = true; 2311 ra_offset = 6; 2312 } 2313 2314 Context context; 2315 context.type = eContextRelativeBranchImmediate; 2316 context.SetImmediate(current_inst_size + offset); 2317 2318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2319 target)) 2320 return false; 2321 2322 if (update_ra) { 2323 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2324 pc + ra_offset)) 2325 return false; 2326 } 2327 return true; 2328 } 2329 2330 /* Emulate micromips jump instructions. 2331 JALR16,JALRS16 2332 */ 2333 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { 2334 bool success = false; 2335 uint32_t ra_offset = 0; 2336 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2337 2338 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2339 2340 uint32_t pc = 2341 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2342 if (!success) 2343 return false; 2344 2345 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, 2346 dwarf_zero_mips + rs, 0, &success); 2347 if (!success) 2348 return false; 2349 2350 if (!strcasecmp(op_name, "JALR16_MM")) 2351 ra_offset = 6; // 2-byte instruction with 4-byte delay slot. 2352 else if (!strcasecmp(op_name, "JALRS16_MM")) 2353 ra_offset = 4; // 2-byte instruction with 2-byte delay slot. 2354 2355 Context context; 2356 2357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2358 rs_val)) 2359 return false; 2360 2361 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2362 pc + ra_offset)) 2363 return false; 2364 2365 return true; 2366 } 2367 2368 /* Emulate JALS and JALX instructions. 2369 JALS 32 bit instruction with short (2-byte) delay slot. 2370 JALX 32 bit instruction with 4-byte delay slot. 2371 */ 2372 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) { 2373 bool success = false; 2374 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0; 2375 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2376 2377 /* 2378 * JALS target 2379 * RA = PC + 6 2380 * offset = sign_ext (offset << 1) 2381 * PC = PC[31-27] | offset 2382 * JALX target 2383 * RA = PC + 8 2384 * offset = sign_ext (offset << 2) 2385 * PC = PC[31-28] | offset 2386 */ 2387 offset = insn.getOperand(0).getImm(); 2388 2389 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2390 if (!success) 2391 return false; 2392 2393 // These are PC-region branches and not PC-relative. 2394 if (!strcasecmp(op_name, "JALS_MM")) { 2395 // target address is in the “current” 128 MB-aligned region 2396 target = (pc & 0xF8000000UL) | offset; 2397 ra_offset = 6; 2398 } else if (!strcasecmp(op_name, "JALX_MM")) { 2399 // target address is in the “current” 256 MB-aligned region 2400 target = (pc & 0xF0000000UL) | offset; 2401 ra_offset = 8; 2402 } 2403 2404 Context context; 2405 2406 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2407 target)) 2408 return false; 2409 2410 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2411 pc + ra_offset)) 2412 return false; 2413 2414 return true; 2415 } 2416 2417 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) { 2418 bool success = false; 2419 uint32_t rs = 0, rt = 0; 2420 int32_t pc = 0, rs_val = 0; 2421 2422 /* 2423 JALRS rt, rs 2424 GPR[rt] <- PC + 6 2425 PC <- GPR[rs] 2426 */ 2427 2428 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2429 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 2430 2431 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2432 dwarf_zero_mips + rs, 0, &success); 2433 if (!success) 2434 return false; 2435 2436 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2437 if (!success) 2438 return false; 2439 2440 Context context; 2441 2442 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2443 rs_val)) 2444 return false; 2445 2446 // This is 4-byte instruction with 2-byte delay slot. 2447 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 2448 pc + 6)) 2449 return false; 2450 2451 return true; 2452 } 2453 2454 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) { 2455 bool success = false; 2456 int32_t offset, pc, target; 2457 2458 /* 2459 * BAL offset 2460 * offset = sign_ext (offset << 2) 2461 * RA = PC + 8 2462 * PC = PC + offset 2463 */ 2464 offset = insn.getOperand(0).getImm(); 2465 2466 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2467 if (!success) 2468 return false; 2469 2470 target = pc + offset; 2471 2472 Context context; 2473 2474 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2475 target)) 2476 return false; 2477 2478 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2479 pc + 8)) 2480 return false; 2481 2482 return true; 2483 } 2484 2485 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) { 2486 bool success = false; 2487 int32_t offset, pc, target; 2488 2489 /* 2490 * BALC offset 2491 * offset = sign_ext (offset << 2) 2492 * RA = PC + 4 2493 * PC = PC + 4 + offset 2494 */ 2495 offset = insn.getOperand(0).getImm(); 2496 2497 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2498 if (!success) 2499 return false; 2500 2501 target = pc + offset; 2502 2503 Context context; 2504 2505 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2506 target)) 2507 return false; 2508 2509 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2510 pc + 4)) 2511 return false; 2512 2513 return true; 2514 } 2515 2516 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) { 2517 bool success = false; 2518 int32_t offset, pc, target; 2519 2520 /* 2521 * BC offset 2522 * offset = sign_ext (offset << 2) 2523 * PC = PC + 4 + offset 2524 */ 2525 offset = insn.getOperand(0).getImm(); 2526 2527 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2528 if (!success) 2529 return false; 2530 2531 target = pc + offset; 2532 2533 Context context; 2534 2535 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2536 target)) 2537 return false; 2538 2539 return true; 2540 } 2541 2542 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) { 2543 bool success = false; 2544 uint32_t offset, pc; 2545 2546 /* 2547 * J offset 2548 * offset = sign_ext (offset << 2) 2549 * PC = PC[63-28] | offset 2550 */ 2551 offset = insn.getOperand(0).getImm(); 2552 2553 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2554 if (!success) 2555 return false; 2556 2557 /* This is a PC-region branch and not PC-relative */ 2558 pc = (pc & 0xF0000000UL) | offset; 2559 2560 Context context; 2561 2562 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc)) 2563 return false; 2564 2565 return true; 2566 } 2567 2568 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) { 2569 bool success = false; 2570 uint32_t offset, target, pc; 2571 2572 /* 2573 * JAL offset 2574 * offset = sign_ext (offset << 2) 2575 * PC = PC[63-28] | offset 2576 */ 2577 offset = insn.getOperand(0).getImm(); 2578 2579 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2580 if (!success) 2581 return false; 2582 2583 /* This is a PC-region branch and not PC-relative */ 2584 target = (pc & 0xF0000000UL) | offset; 2585 2586 Context context; 2587 2588 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2589 target)) 2590 return false; 2591 2592 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2593 pc + 8)) 2594 return false; 2595 2596 return true; 2597 } 2598 2599 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) { 2600 bool success = false; 2601 uint32_t rs, rt; 2602 uint32_t pc, rs_val; 2603 2604 /* 2605 * JALR rt, rs 2606 * GPR[rt] = PC + 8 2607 * PC = GPR[rs] 2608 */ 2609 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2610 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 2611 2612 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2613 if (!success) 2614 return false; 2615 2616 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, 2617 &success); 2618 if (!success) 2619 return false; 2620 2621 Context context; 2622 2623 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2624 rs_val)) 2625 return false; 2626 2627 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 2628 pc + 8)) 2629 return false; 2630 2631 return true; 2632 } 2633 2634 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) { 2635 bool success = false; 2636 uint32_t rt; 2637 int32_t target, offset, pc, rt_val; 2638 2639 /* 2640 * JIALC rt, offset 2641 * offset = sign_ext (offset) 2642 * PC = GPR[rt] + offset 2643 * RA = PC + 4 2644 */ 2645 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2646 offset = insn.getOperand(1).getImm(); 2647 2648 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2649 if (!success) 2650 return false; 2651 2652 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2653 dwarf_zero_mips + rt, 0, &success); 2654 if (!success) 2655 return false; 2656 2657 target = rt_val + offset; 2658 2659 Context context; 2660 2661 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2662 target)) 2663 return false; 2664 2665 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2666 pc + 4)) 2667 return false; 2668 2669 return true; 2670 } 2671 2672 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) { 2673 bool success = false; 2674 uint32_t rt; 2675 int32_t target, offset, rt_val; 2676 2677 /* 2678 * JIC rt, offset 2679 * offset = sign_ext (offset) 2680 * PC = GPR[rt] + offset 2681 */ 2682 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2683 offset = insn.getOperand(1).getImm(); 2684 2685 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2686 dwarf_zero_mips + rt, 0, &success); 2687 if (!success) 2688 return false; 2689 2690 target = rt_val + offset; 2691 2692 Context context; 2693 2694 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2695 target)) 2696 return false; 2697 2698 return true; 2699 } 2700 2701 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) { 2702 bool success = false; 2703 uint32_t rs; 2704 uint32_t rs_val; 2705 2706 /* 2707 * JR rs 2708 * PC = GPR[rs] 2709 */ 2710 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2711 2712 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, 2713 &success); 2714 if (!success) 2715 return false; 2716 2717 Context context; 2718 2719 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2720 rs_val)) 2721 return false; 2722 2723 return true; 2724 } 2725 2726 /* 2727 Emulate Branch on FP True/False 2728 BC1F, BC1FL : Branch on FP False (L stands for branch likely) 2729 BC1T, BC1TL : Branch on FP True (L stands for branch likely) 2730 */ 2731 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { 2732 bool success = false; 2733 uint32_t cc, fcsr; 2734 int32_t pc, offset, target = 0; 2735 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2736 2737 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2738 offset = insn.getOperand(1).getImm(); 2739 2740 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2741 if (!success) 2742 return false; 2743 2744 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); 2745 if (!success) 2746 return false; 2747 2748 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2749 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2750 2751 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) { 2752 if ((fcsr & (1 << cc)) == 0) 2753 target = pc + offset; 2754 else 2755 target = pc + 8; 2756 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) { 2757 if ((fcsr & (1 << cc)) != 0) 2758 target = pc + offset; 2759 else 2760 target = pc + 8; 2761 } 2762 Context context; 2763 2764 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2765 target)) 2766 return false; 2767 2768 return true; 2769 } 2770 2771 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) { 2772 bool success = false; 2773 uint32_t ft; 2774 uint32_t ft_val; 2775 int32_t target, pc, offset; 2776 2777 /* 2778 * BC1EQZ ft, offset 2779 * condition <- (FPR[ft].bit0 == 0) 2780 * if condition then 2781 * offset = sign_ext (offset) 2782 * PC = PC + 4 + offset 2783 */ 2784 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2785 offset = insn.getOperand(1).getImm(); 2786 2787 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2788 if (!success) 2789 return false; 2790 2791 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, 2792 &success); 2793 if (!success) 2794 return false; 2795 2796 if ((ft_val & 1) == 0) 2797 target = pc + 4 + offset; 2798 else 2799 target = pc + 8; 2800 2801 Context context; 2802 2803 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2804 target)) 2805 return false; 2806 2807 return true; 2808 } 2809 2810 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) { 2811 bool success = false; 2812 uint32_t ft; 2813 uint32_t ft_val; 2814 int32_t target, pc, offset; 2815 2816 /* 2817 * BC1NEZ ft, offset 2818 * condition <- (FPR[ft].bit0 != 0) 2819 * if condition then 2820 * offset = sign_ext (offset) 2821 * PC = PC + 4 + offset 2822 */ 2823 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2824 offset = insn.getOperand(1).getImm(); 2825 2826 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2827 if (!success) 2828 return false; 2829 2830 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, 2831 &success); 2832 if (!success) 2833 return false; 2834 2835 if ((ft_val & 1) != 0) 2836 target = pc + 4 + offset; 2837 else 2838 target = pc + 8; 2839 2840 Context context; 2841 2842 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2843 target)) 2844 return false; 2845 2846 return true; 2847 } 2848 2849 /* 2850 Emulate MIPS-3D Branch instructions 2851 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes 2852 False/True 2853 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes 2854 False/True 2855 */ 2856 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { 2857 bool success = false; 2858 uint32_t cc, fcsr; 2859 int32_t pc, offset, target = 0; 2860 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2861 2862 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2863 offset = insn.getOperand(1).getImm(); 2864 2865 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2866 if (!success) 2867 return false; 2868 2869 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, 2870 &success); 2871 if (!success) 2872 return false; 2873 2874 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2875 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2876 2877 if (!strcasecmp(op_name, "BC1ANY2F")) { 2878 /* if any one bit is 0 */ 2879 if (((fcsr >> cc) & 3) != 3) 2880 target = pc + offset; 2881 else 2882 target = pc + 8; 2883 } else if (!strcasecmp(op_name, "BC1ANY2T")) { 2884 /* if any one bit is 1 */ 2885 if (((fcsr >> cc) & 3) != 0) 2886 target = pc + offset; 2887 else 2888 target = pc + 8; 2889 } else if (!strcasecmp(op_name, "BC1ANY4F")) { 2890 /* if any one bit is 0 */ 2891 if (((fcsr >> cc) & 0xf) != 0xf) 2892 target = pc + offset; 2893 else 2894 target = pc + 8; 2895 } else if (!strcasecmp(op_name, "BC1ANY4T")) { 2896 /* if any one bit is 1 */ 2897 if (((fcsr >> cc) & 0xf) != 0) 2898 target = pc + offset; 2899 else 2900 target = pc + 8; 2901 } 2902 Context context; 2903 2904 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2905 target)) 2906 return false; 2907 2908 return true; 2909 } 2910 2911 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) { 2912 return Emulate_MSA_Branch_DF(insn, 1, true); 2913 } 2914 2915 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) { 2916 return Emulate_MSA_Branch_DF(insn, 2, true); 2917 } 2918 2919 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) { 2920 return Emulate_MSA_Branch_DF(insn, 4, true); 2921 } 2922 2923 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) { 2924 return Emulate_MSA_Branch_DF(insn, 8, true); 2925 } 2926 2927 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) { 2928 return Emulate_MSA_Branch_DF(insn, 1, false); 2929 } 2930 2931 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) { 2932 return Emulate_MSA_Branch_DF(insn, 2, false); 2933 } 2934 2935 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) { 2936 return Emulate_MSA_Branch_DF(insn, 4, false); 2937 } 2938 2939 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) { 2940 return Emulate_MSA_Branch_DF(insn, 8, false); 2941 } 2942 2943 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn, 2944 int element_byte_size, 2945 bool bnz) { 2946 bool success = false, branch_hit = true; 2947 int32_t target = 0; 2948 RegisterValue reg_value; 2949 const uint8_t *ptr = NULL; 2950 2951 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2952 int32_t offset = insn.getOperand(1).getImm(); 2953 2954 int32_t pc = 2955 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2956 if (!success) 2957 return false; 2958 2959 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2960 ptr = (const uint8_t *)reg_value.GetBytes(); 2961 else 2962 return false; 2963 2964 for (int i = 0; i < 16 / element_byte_size; i++) { 2965 switch (element_byte_size) { 2966 case 1: 2967 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz)) 2968 branch_hit = false; 2969 break; 2970 case 2: 2971 if ((*(const uint16_t *)ptr == 0 && bnz) || 2972 (*(const uint16_t *)ptr != 0 && !bnz)) 2973 branch_hit = false; 2974 break; 2975 case 4: 2976 if ((*(const uint32_t *)ptr == 0 && bnz) || 2977 (*(const uint32_t *)ptr != 0 && !bnz)) 2978 branch_hit = false; 2979 break; 2980 case 8: 2981 if ((*(const uint64_t *)ptr == 0 && bnz) || 2982 (*(const uint64_t *)ptr != 0 && !bnz)) 2983 branch_hit = false; 2984 break; 2985 } 2986 if (!branch_hit) 2987 break; 2988 ptr = ptr + element_byte_size; 2989 } 2990 2991 if (branch_hit) 2992 target = pc + offset; 2993 else 2994 target = pc + 8; 2995 2996 Context context; 2997 context.type = eContextRelativeBranchImmediate; 2998 2999 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 3000 target)) 3001 return false; 3002 3003 return true; 3004 } 3005 3006 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) { 3007 return Emulate_MSA_Branch_V(insn, true); 3008 } 3009 3010 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) { 3011 return Emulate_MSA_Branch_V(insn, false); 3012 } 3013 3014 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn, 3015 bool bnz) { 3016 bool success = false; 3017 int32_t target = 0; 3018 llvm::APInt wr_val = llvm::APInt::getNullValue(128); 3019 llvm::APInt fail_value = llvm::APInt::getMaxValue(128); 3020 llvm::APInt zero_value = llvm::APInt::getNullValue(128); 3021 RegisterValue reg_value; 3022 3023 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 3024 int32_t offset = insn.getOperand(1).getImm(); 3025 3026 int32_t pc = 3027 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 3028 if (!success) 3029 return false; 3030 3031 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 3032 wr_val = reg_value.GetAsUInt128(fail_value); 3033 else 3034 return false; 3035 3036 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || 3037 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) 3038 target = pc + offset; 3039 else 3040 target = pc + 8; 3041 3042 Context context; 3043 context.type = eContextRelativeBranchImmediate; 3044 3045 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 3046 target)) 3047 return false; 3048 3049 return true; 3050 } 3051 3052 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) { 3053 bool success = false; 3054 uint32_t base; 3055 int32_t imm, address; 3056 Context bad_vaddr_context; 3057 3058 uint32_t num_operands = insn.getNumOperands(); 3059 base = 3060 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 3061 imm = insn.getOperand(num_operands - 1).getImm(); 3062 3063 RegisterInfo reg_info_base; 3064 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 3065 reg_info_base)) 3066 return false; 3067 3068 /* read base register */ 3069 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 3070 dwarf_zero_mips + base, 0, &success); 3071 if (!success) 3072 return false; 3073 3074 /* destination address */ 3075 address = address + imm; 3076 3077 /* Set the bad_vaddr register with base address used in the instruction */ 3078 bad_vaddr_context.type = eContextInvalid; 3079 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 3080 address); 3081 3082 return true; 3083 } 3084 3085 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) { 3086 bool success = false; 3087 uint32_t base, index; 3088 int32_t address, index_address; 3089 Context bad_vaddr_context; 3090 3091 uint32_t num_operands = insn.getNumOperands(); 3092 base = 3093 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 3094 index = 3095 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg()); 3096 3097 RegisterInfo reg_info_base, reg_info_index; 3098 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 3099 reg_info_base)) 3100 return false; 3101 3102 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index, 3103 reg_info_index)) 3104 return false; 3105 3106 /* read base register */ 3107 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 3108 dwarf_zero_mips + base, 0, &success); 3109 if (!success) 3110 return false; 3111 3112 /* read index register */ 3113 index_address = (int32_t)ReadRegisterUnsigned( 3114 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success); 3115 if (!success) 3116 return false; 3117 3118 /* destination address */ 3119 address = address + index_address; 3120 3121 /* Set the bad_vaddr register with base address used in the instruction */ 3122 bad_vaddr_context.type = eContextInvalid; 3123 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 3124 address); 3125 3126 return true; 3127 } 3128