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