1 //===-- EmulateInstructionMIPS64.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 "EmulateInstructionMIPS64.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/Host/PosixApi.h" 17 #include "lldb/Symbol/UnwindPlan.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(EmulateInstructionMIPS64, InstructionMIPS64) 44 45 #define UInt(x) ((uint64_t)x) 46 #define integer int64_t 47 48 // 49 // EmulateInstructionMIPS64 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 EmulateInstructionMIPS64::EmulateInstructionMIPS64( 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 if (arch_flags & ArchSpec::eMIPSAse_mips16) 149 features += "+mips16,"; 150 if (arch_flags & ArchSpec::eMIPSAse_micromips) 151 features += "+micromips,"; 152 153 m_reg_info.reset(target->createMCRegInfo(triple.getTriple())); 154 assert(m_reg_info.get()); 155 156 m_insn_info.reset(target->createMCInstrInfo()); 157 assert(m_insn_info.get()); 158 159 llvm::MCTargetOptions MCOptions; 160 m_asm_info.reset( 161 target->createMCAsmInfo(*m_reg_info, triple.getTriple(), MCOptions)); 162 m_subtype_info.reset( 163 target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); 164 assert(m_asm_info.get() && m_subtype_info.get()); 165 166 m_context = std::make_unique<llvm::MCContext>( 167 triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get()); 168 assert(m_context.get()); 169 170 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); 171 assert(m_disasm.get()); 172 } 173 174 void EmulateInstructionMIPS64::Initialize() { 175 PluginManager::RegisterPlugin(GetPluginNameStatic(), 176 GetPluginDescriptionStatic(), CreateInstance); 177 } 178 179 void EmulateInstructionMIPS64::Terminate() { 180 PluginManager::UnregisterPlugin(CreateInstance); 181 } 182 183 llvm::StringRef EmulateInstructionMIPS64::GetPluginDescriptionStatic() { 184 return "Emulate instructions for the MIPS64 architecture."; 185 } 186 187 EmulateInstruction * 188 EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch, 189 InstructionType inst_type) { 190 if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic( 191 inst_type)) { 192 if (arch.GetTriple().getArch() == llvm::Triple::mips64 || 193 arch.GetTriple().getArch() == llvm::Triple::mips64el) { 194 return new EmulateInstructionMIPS64(arch); 195 } 196 } 197 198 return nullptr; 199 } 200 201 bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) { 202 return arch.GetTriple().getArch() == llvm::Triple::mips64 || 203 arch.GetTriple().getArch() == llvm::Triple::mips64el; 204 } 205 206 const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num, 207 bool alternate_name) { 208 if (alternate_name) { 209 switch (reg_num) { 210 case dwarf_sp_mips64: 211 return "r29"; 212 case dwarf_r30_mips64: 213 return "r30"; 214 case dwarf_ra_mips64: 215 return "r31"; 216 case dwarf_f0_mips64: 217 return "f0"; 218 case dwarf_f1_mips64: 219 return "f1"; 220 case dwarf_f2_mips64: 221 return "f2"; 222 case dwarf_f3_mips64: 223 return "f3"; 224 case dwarf_f4_mips64: 225 return "f4"; 226 case dwarf_f5_mips64: 227 return "f5"; 228 case dwarf_f6_mips64: 229 return "f6"; 230 case dwarf_f7_mips64: 231 return "f7"; 232 case dwarf_f8_mips64: 233 return "f8"; 234 case dwarf_f9_mips64: 235 return "f9"; 236 case dwarf_f10_mips64: 237 return "f10"; 238 case dwarf_f11_mips64: 239 return "f11"; 240 case dwarf_f12_mips64: 241 return "f12"; 242 case dwarf_f13_mips64: 243 return "f13"; 244 case dwarf_f14_mips64: 245 return "f14"; 246 case dwarf_f15_mips64: 247 return "f15"; 248 case dwarf_f16_mips64: 249 return "f16"; 250 case dwarf_f17_mips64: 251 return "f17"; 252 case dwarf_f18_mips64: 253 return "f18"; 254 case dwarf_f19_mips64: 255 return "f19"; 256 case dwarf_f20_mips64: 257 return "f20"; 258 case dwarf_f21_mips64: 259 return "f21"; 260 case dwarf_f22_mips64: 261 return "f22"; 262 case dwarf_f23_mips64: 263 return "f23"; 264 case dwarf_f24_mips64: 265 return "f24"; 266 case dwarf_f25_mips64: 267 return "f25"; 268 case dwarf_f26_mips64: 269 return "f26"; 270 case dwarf_f27_mips64: 271 return "f27"; 272 case dwarf_f28_mips64: 273 return "f28"; 274 case dwarf_f29_mips64: 275 return "f29"; 276 case dwarf_f30_mips64: 277 return "f30"; 278 case dwarf_f31_mips64: 279 return "f31"; 280 case dwarf_w0_mips64: 281 return "w0"; 282 case dwarf_w1_mips64: 283 return "w1"; 284 case dwarf_w2_mips64: 285 return "w2"; 286 case dwarf_w3_mips64: 287 return "w3"; 288 case dwarf_w4_mips64: 289 return "w4"; 290 case dwarf_w5_mips64: 291 return "w5"; 292 case dwarf_w6_mips64: 293 return "w6"; 294 case dwarf_w7_mips64: 295 return "w7"; 296 case dwarf_w8_mips64: 297 return "w8"; 298 case dwarf_w9_mips64: 299 return "w9"; 300 case dwarf_w10_mips64: 301 return "w10"; 302 case dwarf_w11_mips64: 303 return "w11"; 304 case dwarf_w12_mips64: 305 return "w12"; 306 case dwarf_w13_mips64: 307 return "w13"; 308 case dwarf_w14_mips64: 309 return "w14"; 310 case dwarf_w15_mips64: 311 return "w15"; 312 case dwarf_w16_mips64: 313 return "w16"; 314 case dwarf_w17_mips64: 315 return "w17"; 316 case dwarf_w18_mips64: 317 return "w18"; 318 case dwarf_w19_mips64: 319 return "w19"; 320 case dwarf_w20_mips64: 321 return "w20"; 322 case dwarf_w21_mips64: 323 return "w21"; 324 case dwarf_w22_mips64: 325 return "w22"; 326 case dwarf_w23_mips64: 327 return "w23"; 328 case dwarf_w24_mips64: 329 return "w24"; 330 case dwarf_w25_mips64: 331 return "w25"; 332 case dwarf_w26_mips64: 333 return "w26"; 334 case dwarf_w27_mips64: 335 return "w27"; 336 case dwarf_w28_mips64: 337 return "w28"; 338 case dwarf_w29_mips64: 339 return "w29"; 340 case dwarf_w30_mips64: 341 return "w30"; 342 case dwarf_w31_mips64: 343 return "w31"; 344 case dwarf_mir_mips64: 345 return "mir"; 346 case dwarf_mcsr_mips64: 347 return "mcsr"; 348 case dwarf_config5_mips64: 349 return "config5"; 350 default: 351 break; 352 } 353 return nullptr; 354 } 355 356 switch (reg_num) { 357 case dwarf_zero_mips64: 358 return "r0"; 359 case dwarf_r1_mips64: 360 return "r1"; 361 case dwarf_r2_mips64: 362 return "r2"; 363 case dwarf_r3_mips64: 364 return "r3"; 365 case dwarf_r4_mips64: 366 return "r4"; 367 case dwarf_r5_mips64: 368 return "r5"; 369 case dwarf_r6_mips64: 370 return "r6"; 371 case dwarf_r7_mips64: 372 return "r7"; 373 case dwarf_r8_mips64: 374 return "r8"; 375 case dwarf_r9_mips64: 376 return "r9"; 377 case dwarf_r10_mips64: 378 return "r10"; 379 case dwarf_r11_mips64: 380 return "r11"; 381 case dwarf_r12_mips64: 382 return "r12"; 383 case dwarf_r13_mips64: 384 return "r13"; 385 case dwarf_r14_mips64: 386 return "r14"; 387 case dwarf_r15_mips64: 388 return "r15"; 389 case dwarf_r16_mips64: 390 return "r16"; 391 case dwarf_r17_mips64: 392 return "r17"; 393 case dwarf_r18_mips64: 394 return "r18"; 395 case dwarf_r19_mips64: 396 return "r19"; 397 case dwarf_r20_mips64: 398 return "r20"; 399 case dwarf_r21_mips64: 400 return "r21"; 401 case dwarf_r22_mips64: 402 return "r22"; 403 case dwarf_r23_mips64: 404 return "r23"; 405 case dwarf_r24_mips64: 406 return "r24"; 407 case dwarf_r25_mips64: 408 return "r25"; 409 case dwarf_r26_mips64: 410 return "r26"; 411 case dwarf_r27_mips64: 412 return "r27"; 413 case dwarf_gp_mips64: 414 return "gp"; 415 case dwarf_sp_mips64: 416 return "sp"; 417 case dwarf_r30_mips64: 418 return "fp"; 419 case dwarf_ra_mips64: 420 return "ra"; 421 case dwarf_sr_mips64: 422 return "sr"; 423 case dwarf_lo_mips64: 424 return "lo"; 425 case dwarf_hi_mips64: 426 return "hi"; 427 case dwarf_bad_mips64: 428 return "bad"; 429 case dwarf_cause_mips64: 430 return "cause"; 431 case dwarf_pc_mips64: 432 return "pc"; 433 case dwarf_f0_mips64: 434 return "f0"; 435 case dwarf_f1_mips64: 436 return "f1"; 437 case dwarf_f2_mips64: 438 return "f2"; 439 case dwarf_f3_mips64: 440 return "f3"; 441 case dwarf_f4_mips64: 442 return "f4"; 443 case dwarf_f5_mips64: 444 return "f5"; 445 case dwarf_f6_mips64: 446 return "f6"; 447 case dwarf_f7_mips64: 448 return "f7"; 449 case dwarf_f8_mips64: 450 return "f8"; 451 case dwarf_f9_mips64: 452 return "f9"; 453 case dwarf_f10_mips64: 454 return "f10"; 455 case dwarf_f11_mips64: 456 return "f11"; 457 case dwarf_f12_mips64: 458 return "f12"; 459 case dwarf_f13_mips64: 460 return "f13"; 461 case dwarf_f14_mips64: 462 return "f14"; 463 case dwarf_f15_mips64: 464 return "f15"; 465 case dwarf_f16_mips64: 466 return "f16"; 467 case dwarf_f17_mips64: 468 return "f17"; 469 case dwarf_f18_mips64: 470 return "f18"; 471 case dwarf_f19_mips64: 472 return "f19"; 473 case dwarf_f20_mips64: 474 return "f20"; 475 case dwarf_f21_mips64: 476 return "f21"; 477 case dwarf_f22_mips64: 478 return "f22"; 479 case dwarf_f23_mips64: 480 return "f23"; 481 case dwarf_f24_mips64: 482 return "f24"; 483 case dwarf_f25_mips64: 484 return "f25"; 485 case dwarf_f26_mips64: 486 return "f26"; 487 case dwarf_f27_mips64: 488 return "f27"; 489 case dwarf_f28_mips64: 490 return "f28"; 491 case dwarf_f29_mips64: 492 return "f29"; 493 case dwarf_f30_mips64: 494 return "f30"; 495 case dwarf_f31_mips64: 496 return "f31"; 497 case dwarf_fcsr_mips64: 498 return "fcsr"; 499 case dwarf_fir_mips64: 500 return "fir"; 501 case dwarf_w0_mips64: 502 return "w0"; 503 case dwarf_w1_mips64: 504 return "w1"; 505 case dwarf_w2_mips64: 506 return "w2"; 507 case dwarf_w3_mips64: 508 return "w3"; 509 case dwarf_w4_mips64: 510 return "w4"; 511 case dwarf_w5_mips64: 512 return "w5"; 513 case dwarf_w6_mips64: 514 return "w6"; 515 case dwarf_w7_mips64: 516 return "w7"; 517 case dwarf_w8_mips64: 518 return "w8"; 519 case dwarf_w9_mips64: 520 return "w9"; 521 case dwarf_w10_mips64: 522 return "w10"; 523 case dwarf_w11_mips64: 524 return "w11"; 525 case dwarf_w12_mips64: 526 return "w12"; 527 case dwarf_w13_mips64: 528 return "w13"; 529 case dwarf_w14_mips64: 530 return "w14"; 531 case dwarf_w15_mips64: 532 return "w15"; 533 case dwarf_w16_mips64: 534 return "w16"; 535 case dwarf_w17_mips64: 536 return "w17"; 537 case dwarf_w18_mips64: 538 return "w18"; 539 case dwarf_w19_mips64: 540 return "w19"; 541 case dwarf_w20_mips64: 542 return "w20"; 543 case dwarf_w21_mips64: 544 return "w21"; 545 case dwarf_w22_mips64: 546 return "w22"; 547 case dwarf_w23_mips64: 548 return "w23"; 549 case dwarf_w24_mips64: 550 return "w24"; 551 case dwarf_w25_mips64: 552 return "w25"; 553 case dwarf_w26_mips64: 554 return "w26"; 555 case dwarf_w27_mips64: 556 return "w27"; 557 case dwarf_w28_mips64: 558 return "w28"; 559 case dwarf_w29_mips64: 560 return "w29"; 561 case dwarf_w30_mips64: 562 return "w30"; 563 case dwarf_w31_mips64: 564 return "w31"; 565 case dwarf_mcsr_mips64: 566 return "mcsr"; 567 case dwarf_mir_mips64: 568 return "mir"; 569 case dwarf_config5_mips64: 570 return "config5"; 571 } 572 return nullptr; 573 } 574 575 bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind, 576 uint32_t reg_num, 577 RegisterInfo ®_info) { 578 if (reg_kind == eRegisterKindGeneric) { 579 switch (reg_num) { 580 case LLDB_REGNUM_GENERIC_PC: 581 reg_kind = eRegisterKindDWARF; 582 reg_num = dwarf_pc_mips64; 583 break; 584 case LLDB_REGNUM_GENERIC_SP: 585 reg_kind = eRegisterKindDWARF; 586 reg_num = dwarf_sp_mips64; 587 break; 588 case LLDB_REGNUM_GENERIC_FP: 589 reg_kind = eRegisterKindDWARF; 590 reg_num = dwarf_r30_mips64; 591 break; 592 case LLDB_REGNUM_GENERIC_RA: 593 reg_kind = eRegisterKindDWARF; 594 reg_num = dwarf_ra_mips64; 595 break; 596 case LLDB_REGNUM_GENERIC_FLAGS: 597 reg_kind = eRegisterKindDWARF; 598 reg_num = dwarf_sr_mips64; 599 break; 600 default: 601 return false; 602 } 603 } 604 605 if (reg_kind == eRegisterKindDWARF) { 606 ::memset(®_info, 0, sizeof(RegisterInfo)); 607 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 608 609 if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 || 610 reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 || 611 reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) { 612 reg_info.byte_size = 4; 613 reg_info.format = eFormatHex; 614 reg_info.encoding = eEncodingUint; 615 } else if ((int)reg_num >= dwarf_zero_mips64 && 616 (int)reg_num <= dwarf_f31_mips64) { 617 reg_info.byte_size = 8; 618 reg_info.format = eFormatHex; 619 reg_info.encoding = eEncodingUint; 620 } else if ((int)reg_num >= dwarf_w0_mips64 && 621 (int)reg_num <= dwarf_w31_mips64) { 622 reg_info.byte_size = 16; 623 reg_info.format = eFormatVectorOfUInt8; 624 reg_info.encoding = eEncodingVector; 625 } else { 626 return false; 627 } 628 629 reg_info.name = GetRegisterName(reg_num, false); 630 reg_info.alt_name = GetRegisterName(reg_num, true); 631 reg_info.kinds[eRegisterKindDWARF] = reg_num; 632 633 switch (reg_num) { 634 case dwarf_r30_mips64: 635 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 636 break; 637 case dwarf_ra_mips64: 638 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 639 break; 640 case dwarf_sp_mips64: 641 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 642 break; 643 case dwarf_pc_mips64: 644 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 645 break; 646 case dwarf_sr_mips64: 647 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 648 break; 649 default: 650 break; 651 } 652 return true; 653 } 654 return false; 655 } 656 657 EmulateInstructionMIPS64::MipsOpcode * 658 EmulateInstructionMIPS64::GetOpcodeForInstruction(llvm::StringRef op_name) { 659 static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = { 660 // Prologue/Epilogue instructions 661 {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, 662 "DADDIU rt, rs, immediate"}, 663 {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, 664 "ADDIU rt, rs, immediate"}, 665 {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)"}, 666 {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)"}, 667 {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 668 "DSUBU rd, rs, rt"}, 669 {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 670 "SUBU rd, rs, rt"}, 671 {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 672 "DADDU rd, rs, rt"}, 673 {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 674 "ADDU rd, rs, rt"}, 675 {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate"}, 676 677 // Load/Store instructions 678 /* Following list of emulated instructions are required by implementation 679 of hardware watchpoint 680 for MIPS in lldb. As we just need the address accessed by instructions, 681 we have generalised 682 all these instructions in 2 functions depending on their addressing 683 modes */ 684 685 {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 686 "LB rt, offset(base)"}, 687 {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 688 "LBE rt, offset(base)"}, 689 {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 690 "LBU rt, offset(base)"}, 691 {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 692 "LBUE rt, offset(base)"}, 693 {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 694 "LDC1 ft, offset(base)"}, 695 {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 696 "LDL rt, offset(base)"}, 697 {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 698 "LDR rt, offset(base)"}, 699 {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 700 "LLD rt, offset(base)"}, 701 {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 702 "LDC2 rt, offset(base)"}, 703 {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 704 "LDXC1 fd, index (base)"}, 705 {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 706 "LH rt, offset(base)"}, 707 {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 708 "LHE rt, offset(base)"}, 709 {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 710 "LHU rt, offset(base)"}, 711 {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 712 "LHUE rt, offset(base)"}, 713 {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 714 "LL rt, offset(base)"}, 715 {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 716 "LLE rt, offset(base)"}, 717 {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 718 "LUXC1 fd, index (base)"}, 719 {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 720 "LW rt, offset(rs)"}, 721 {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 722 "LWC1 ft, offset(base)"}, 723 {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 724 "LWC2 rt, offset(base)"}, 725 {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 726 "LWE rt, offset(base)"}, 727 {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 728 "LWL rt, offset(base)"}, 729 {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 730 "LWLE rt, offset(base)"}, 731 {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 732 "LWR rt, offset(base)"}, 733 {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 734 "LWRE rt, offset(base)"}, 735 {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 736 "LWXC1 fd, index (base)"}, 737 738 {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 739 "SB rt, offset(base)"}, 740 {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 741 "SBE rt, offset(base)"}, 742 {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 743 "SC rt, offset(base)"}, 744 {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 745 "SCE rt, offset(base)"}, 746 {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 747 "SCD rt, offset(base)"}, 748 {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 749 "SDL rt, offset(base)"}, 750 {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 751 "SDR rt, offset(base)"}, 752 {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 753 "SDC1 ft, offset(base)"}, 754 {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 755 "SDC2 rt, offset(base)"}, 756 {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 757 "SDXC1 fs, index (base)"}, 758 {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 759 "SH rt, offset(base)"}, 760 {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 761 "SHE rt, offset(base)"}, 762 {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 763 "SUXC1 fs, index (base)"}, 764 {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 765 "SW rt, offset(rs)"}, 766 {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 767 "SWC1 ft, offset(base)"}, 768 {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 769 "SWC2 rt, offset(base)"}, 770 {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 771 "SWE rt, offset(base)"}, 772 {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 773 "SWL rt, offset(base)"}, 774 {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 775 "SWLE rt, offset(base)"}, 776 {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 777 "SWR rt, offset(base)"}, 778 {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 779 "SWRE rt, offset(base)"}, 780 {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 781 "SWXC1 fs, index (base)"}, 782 783 // Branch instructions 784 {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"}, 785 {"BEQ64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"}, 786 {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"}, 787 {"BNE64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"}, 788 {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, 789 "BEQL rs,rt,offset"}, 790 {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, 791 "BNEL rs,rt,offset"}, 792 {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 793 "BGEZALL rt,offset"}, 794 {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"}, 795 {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 796 "BGEZAL rs,offset"}, 797 {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"}, 798 {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"}, 799 {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"}, 800 {"BGEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"}, 801 {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 802 "BLEZALC rs,offset"}, 803 {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 804 "BGEZALC rs,offset"}, 805 {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 806 "BLTZALC rs,offset"}, 807 {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 808 "BGTZALC rs,offset"}, 809 {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 810 "BEQZALC rs,offset"}, 811 {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 812 "BNEZALC rs,offset"}, 813 {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 814 "BEQC rs,rt,offset"}, 815 {"BEQC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 816 "BEQC rs,rt,offset"}, 817 {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 818 "BNEC rs,rt,offset"}, 819 {"BNEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 820 "BNEC rs,rt,offset"}, 821 {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 822 "BLTC rs,rt,offset"}, 823 {"BLTC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 824 "BLTC rs,rt,offset"}, 825 {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 826 "BGEC rs,rt,offset"}, 827 {"BGEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 828 "BGEC rs,rt,offset"}, 829 {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 830 "BLTUC rs,rt,offset"}, 831 {"BLTUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 832 "BLTUC rs,rt,offset"}, 833 {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 834 "BGEUC rs,rt,offset"}, 835 {"BGEUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 836 "BGEUC rs,rt,offset"}, 837 {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 838 "BLTZC rt,offset"}, 839 {"BLTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 840 "BLTZC rt,offset"}, 841 {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 842 "BLEZC rt,offset"}, 843 {"BLEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 844 "BLEZC rt,offset"}, 845 {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 846 "BGEZC rt,offset"}, 847 {"BGEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 848 "BGEZC rt,offset"}, 849 {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 850 "BGTZC rt,offset"}, 851 {"BGTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 852 "BGTZC rt,offset"}, 853 {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 854 "BEQZC rt,offset"}, 855 {"BEQZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 856 "BEQZC rt,offset"}, 857 {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 858 "BNEZC rt,offset"}, 859 {"BNEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 860 "BNEZC rt,offset"}, 861 {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"}, 862 {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"}, 863 {"BGTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"}, 864 {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"}, 865 {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"}, 866 {"BLEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"}, 867 {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"}, 868 {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"}, 869 {"BLTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"}, 870 {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 871 "BLTZAL rt,offset"}, 872 {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 873 "BLTZALL rt,offset"}, 874 {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"}, 875 {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 876 "BOVC rs,rt,offset"}, 877 {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 878 "BNVC rs,rt,offset"}, 879 {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"}, 880 {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"}, 881 {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"}, 882 {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"}, 883 {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"}, 884 {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"}, 885 {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"}, 886 {"JIALC64", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"}, 887 {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"}, 888 {"JIC64", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"}, 889 {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"}, 890 {"JR64", &EmulateInstructionMIPS64::Emulate_JR, "JR target"}, 891 {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"}, 892 {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"}, 893 {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"}, 894 {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch, 895 "BC1FL cc, offset"}, 896 {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch, 897 "BC1TL cc, offset"}, 898 {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ, 899 "BC1EQZ ft, offset"}, 900 {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ, 901 "BC1NEZ ft, offset"}, 902 {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch, 903 "BC1ANY2F cc, offset"}, 904 {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch, 905 "BC1ANY2T cc, offset"}, 906 {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch, 907 "BC1ANY4F cc, offset"}, 908 {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch, 909 "BC1ANY4T cc, offset"}, 910 {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"}, 911 {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"}, 912 {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"}, 913 {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"}, 914 {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"}, 915 {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"}, 916 {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"}, 917 {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"}, 918 {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"}, 919 {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"}, 920 }; 921 922 for (MipsOpcode &opcode : g_opcodes) { 923 if (op_name.equals_insensitive(opcode.op_name)) 924 return &opcode; 925 } 926 return nullptr; 927 } 928 929 bool EmulateInstructionMIPS64::ReadInstruction() { 930 bool success = false; 931 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 932 LLDB_INVALID_ADDRESS, &success); 933 if (success) { 934 Context read_inst_context; 935 read_inst_context.type = eContextReadOpcode; 936 read_inst_context.SetNoArgs(); 937 m_opcode.SetOpcode32( 938 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success), 939 GetByteOrder()); 940 } 941 if (!success) 942 m_addr = LLDB_INVALID_ADDRESS; 943 return success; 944 } 945 946 bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) { 947 bool success = false; 948 llvm::MCInst mc_insn; 949 uint64_t insn_size; 950 DataExtractor data; 951 952 /* Keep the complexity of the decode logic with the llvm::MCDisassembler 953 * class. */ 954 if (m_opcode.GetData(data)) { 955 llvm::MCDisassembler::DecodeStatus decode_status; 956 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); 957 decode_status = m_disasm->getInstruction(mc_insn, insn_size, raw_insn, 958 m_addr, llvm::nulls()); 959 if (decode_status != llvm::MCDisassembler::Success) 960 return false; 961 } 962 963 /* 964 * mc_insn.getOpcode() returns decoded opcode. However to make use 965 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". 966 */ 967 llvm::StringRef op_name = m_insn_info->getName(mc_insn.getOpcode()); 968 969 /* 970 * Decoding has been done already. Just get the call-back function 971 * and emulate the instruction. 972 */ 973 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name); 974 975 if (opcode_data == nullptr) 976 return false; 977 978 uint64_t old_pc = 0, new_pc = 0; 979 const bool auto_advance_pc = 980 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 981 982 if (auto_advance_pc) { 983 old_pc = 984 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 985 if (!success) 986 return false; 987 } 988 989 /* emulate instruction */ 990 success = (this->*opcode_data->callback)(mc_insn); 991 if (!success) 992 return false; 993 994 if (auto_advance_pc) { 995 new_pc = 996 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 997 if (!success) 998 return false; 999 1000 /* If we haven't changed the PC, change it here */ 1001 if (old_pc == new_pc) { 1002 new_pc += 4; 1003 Context context; 1004 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1005 new_pc)) 1006 return false; 1007 } 1008 } 1009 1010 return true; 1011 } 1012 1013 bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind( 1014 UnwindPlan &unwind_plan) { 1015 unwind_plan.Clear(); 1016 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1017 1018 UnwindPlan::RowSP row(new UnwindPlan::Row); 1019 const bool can_replace = false; 1020 1021 // Our previous Call Frame Address is the stack pointer 1022 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0); 1023 1024 // Our previous PC is in the RA 1025 row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64, 1026 can_replace); 1027 1028 unwind_plan.AppendRow(row); 1029 1030 // All other registers are the same. 1031 unwind_plan.SetSourceName("EmulateInstructionMIPS64"); 1032 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1033 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 1034 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1035 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64); 1036 1037 return true; 1038 } 1039 1040 bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) { 1041 switch (regnum) { 1042 case dwarf_r16_mips64: 1043 case dwarf_r17_mips64: 1044 case dwarf_r18_mips64: 1045 case dwarf_r19_mips64: 1046 case dwarf_r20_mips64: 1047 case dwarf_r21_mips64: 1048 case dwarf_r22_mips64: 1049 case dwarf_r23_mips64: 1050 case dwarf_gp_mips64: 1051 case dwarf_sp_mips64: 1052 case dwarf_r30_mips64: 1053 case dwarf_ra_mips64: 1054 return true; 1055 default: 1056 return false; 1057 } 1058 return false; 1059 } 1060 1061 bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) { 1062 // DADDIU rt, rs, immediate 1063 // GPR[rt] <- GPR[rs] + sign_extend(immediate) 1064 1065 uint8_t dst, src; 1066 bool success = false; 1067 const uint32_t imm16 = insn.getOperand(2).getImm(); 1068 int64_t imm = SignedBits(imm16, 15, 0); 1069 1070 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1071 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1072 1073 // If immediate is greater than 2^16 - 1 then clang generate LUI, 1074 // (D)ADDIU,(D)SUBU instructions in prolog. Example lui $1, 0x2 daddiu $1, 1075 // $1, -0x5920 dsubu $sp, $sp, $1 In this case, (D)ADDIU dst and src will be 1076 // same and not equal to sp 1077 if (dst == src) { 1078 Context context; 1079 1080 /* read <src> register */ 1081 const uint64_t src_opd_val = ReadRegisterUnsigned( 1082 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); 1083 if (!success) 1084 return false; 1085 1086 /* Check if this is daddiu sp, sp, imm16 */ 1087 if (dst == dwarf_sp_mips64) { 1088 /* 1089 * From the MIPS IV spec: 1090 * 1091 * The term “unsigned” in the instruction name is a misnomer; this 1092 * operation is 64-bit modulo arithmetic that does not trap on overflow. 1093 * It is appropriate for arithmetic which is not signed, such as address 1094 * arithmetic, or integer arithmetic environments that ignore overflow, 1095 * such as “C” language arithmetic. 1096 * 1097 * Assume 2's complement and rely on unsigned overflow here. 1098 */ 1099 uint64_t result = src_opd_val + imm; 1100 RegisterInfo reg_info_sp; 1101 1102 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp)) 1103 context.SetRegisterPlusOffset(reg_info_sp, imm); 1104 1105 /* We are allocating bytes on stack */ 1106 context.type = eContextAdjustStackPointer; 1107 1108 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, 1109 result); 1110 return true; 1111 } 1112 1113 imm += src_opd_val; 1114 context.SetImmediateSigned(imm); 1115 context.type = eContextImmediate; 1116 1117 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1118 dwarf_zero_mips64 + dst, imm)) 1119 return false; 1120 } 1121 1122 return true; 1123 } 1124 1125 bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) { 1126 uint64_t address; 1127 RegisterInfo reg_info_base; 1128 RegisterInfo reg_info_src; 1129 bool success = false; 1130 uint32_t imm16 = insn.getOperand(2).getImm(); 1131 uint64_t imm = SignedBits(imm16, 15, 0); 1132 uint32_t src, base; 1133 Context bad_vaddr_context; 1134 1135 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1136 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1137 1138 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1139 reg_info_base) || 1140 !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src, 1141 reg_info_src)) 1142 return false; 1143 1144 /* read SP */ 1145 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1146 0, &success); 1147 if (!success) 1148 return false; 1149 1150 /* destination address */ 1151 address = address + imm; 1152 1153 /* We look for sp based non-volatile register stores */ 1154 if (nonvolatile_reg_p(src)) { 1155 Context context; 1156 RegisterValue data_src; 1157 context.type = eContextPushRegisterOnStack; 1158 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1159 1160 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1161 Status error; 1162 1163 if (!ReadRegister(®_info_base, data_src)) 1164 return false; 1165 1166 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1167 eByteOrderLittle, error) == 0) 1168 return false; 1169 1170 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) 1171 return false; 1172 } 1173 1174 /* Set the bad_vaddr register with base address used in the instruction */ 1175 bad_vaddr_context.type = eContextInvalid; 1176 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, 1177 address); 1178 1179 return true; 1180 } 1181 1182 bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) { 1183 bool success = false; 1184 uint32_t src, base; 1185 int64_t imm, address; 1186 Context bad_vaddr_context; 1187 1188 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1189 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1190 imm = insn.getOperand(2).getImm(); 1191 1192 RegisterInfo reg_info_base; 1193 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1194 reg_info_base)) 1195 return false; 1196 1197 /* read base register */ 1198 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1199 0, &success); 1200 if (!success) 1201 return false; 1202 1203 /* destination address */ 1204 address = address + imm; 1205 1206 /* Set the bad_vaddr register with base address used in the instruction */ 1207 bad_vaddr_context.type = eContextInvalid; 1208 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, 1209 address); 1210 1211 if (nonvolatile_reg_p(src)) { 1212 RegisterValue data_src; 1213 RegisterInfo reg_info_src; 1214 1215 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src, 1216 reg_info_src)) 1217 return false; 1218 1219 Context context; 1220 context.type = eContextRegisterLoad; 1221 1222 return WriteRegister(context, ®_info_src, data_src); 1223 } 1224 1225 return false; 1226 } 1227 1228 bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) { 1229 // LUI rt, immediate 1230 // GPR[rt] <- sign_extend(immediate << 16) 1231 1232 const uint32_t imm32 = insn.getOperand(1).getImm() << 16; 1233 int64_t imm = SignedBits(imm32, 31, 0); 1234 uint8_t rt; 1235 Context context; 1236 1237 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1238 context.SetImmediateSigned(imm); 1239 context.type = eContextImmediate; 1240 1241 return WriteRegisterUnsigned(context, eRegisterKindDWARF, 1242 dwarf_zero_mips64 + rt, imm); 1243 } 1244 1245 bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) { 1246 // DSUBU sp, <src>, <rt> 1247 // DADDU sp, <src>, <rt> 1248 // DADDU dst, sp, <rt> 1249 1250 bool success = false; 1251 uint64_t result; 1252 uint8_t src, dst, rt; 1253 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1254 1255 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1256 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1257 1258 /* Check if sp is destination register */ 1259 if (dst == dwarf_sp_mips64) { 1260 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1261 1262 /* read <src> register */ 1263 uint64_t src_opd_val = ReadRegisterUnsigned( 1264 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); 1265 if (!success) 1266 return false; 1267 1268 /* read <rt > register */ 1269 uint64_t rt_opd_val = ReadRegisterUnsigned( 1270 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success); 1271 if (!success) 1272 return false; 1273 1274 if (op_name.equals_insensitive("DSUBU") || 1275 op_name.equals_insensitive("SUBU")) 1276 result = src_opd_val - rt_opd_val; 1277 else 1278 result = src_opd_val + rt_opd_val; 1279 1280 Context context; 1281 RegisterInfo reg_info_sp; 1282 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp)) 1283 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val); 1284 1285 /* We are allocating bytes on stack */ 1286 context.type = eContextAdjustStackPointer; 1287 1288 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result); 1289 1290 return true; 1291 } else if (src == dwarf_sp_mips64) { 1292 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1293 1294 /* read <src> register */ 1295 uint64_t src_opd_val = ReadRegisterUnsigned( 1296 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); 1297 if (!success) 1298 return false; 1299 1300 /* read <rt> register */ 1301 uint64_t rt_opd_val = ReadRegisterUnsigned( 1302 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success); 1303 if (!success) 1304 return false; 1305 1306 Context context; 1307 1308 if (op_name.equals_insensitive("DSUBU") || 1309 op_name.equals_insensitive("SUBU")) 1310 result = src_opd_val - rt_opd_val; 1311 else 1312 result = src_opd_val + rt_opd_val; 1313 1314 context.SetImmediateSigned(result); 1315 context.type = eContextImmediate; 1316 1317 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1318 dwarf_zero_mips64 + dst, result)) 1319 return false; 1320 } 1321 1322 return true; 1323 } 1324 1325 /* 1326 Emulate below MIPS branch instructions. 1327 BEQ, BNE : Branch on condition 1328 BEQL, BNEL : Branch likely 1329 */ 1330 bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) { 1331 bool success = false; 1332 uint32_t rs, rt; 1333 int64_t offset, pc, rs_val, rt_val, target = 0; 1334 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1335 1336 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1337 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1338 offset = insn.getOperand(2).getImm(); 1339 1340 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1341 if (!success) 1342 return false; 1343 1344 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1345 dwarf_zero_mips64 + rs, 0, &success); 1346 if (!success) 1347 return false; 1348 1349 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1350 dwarf_zero_mips64 + rt, 0, &success); 1351 if (!success) 1352 return false; 1353 1354 if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL") || 1355 op_name.equals_insensitive("BEQ64")) { 1356 if (rs_val == rt_val) 1357 target = pc + offset; 1358 else 1359 target = pc + 8; 1360 } else if (op_name.equals_insensitive("BNE") || 1361 op_name.equals_insensitive("BNEL") || 1362 op_name.equals_insensitive("BNE64")) { 1363 if (rs_val != rt_val) 1364 target = pc + offset; 1365 else 1366 target = pc + 8; 1367 } 1368 1369 Context context; 1370 context.type = eContextRelativeBranchImmediate; 1371 context.SetImmediate(offset); 1372 1373 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1374 target); 1375 } 1376 1377 /* 1378 Emulate below MIPS Non-Compact conditional branch and link instructions. 1379 BLTZAL, BGEZAL : 1380 BLTZALL, BGEZALL : Branch likely 1381 */ 1382 bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) { 1383 bool success = false; 1384 uint32_t rs; 1385 int64_t offset, pc, target = 0; 1386 int64_t rs_val; 1387 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1388 1389 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1390 offset = insn.getOperand(1).getImm(); 1391 1392 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1393 if (!success) 1394 return false; 1395 1396 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1397 dwarf_zero_mips64 + rs, 0, &success); 1398 if (!success) 1399 return false; 1400 1401 if (op_name.equals_insensitive("BLTZAL") || 1402 op_name.equals_insensitive("BLTZALL")) { 1403 if (rs_val < 0) 1404 target = pc + offset; 1405 else 1406 target = pc + 8; 1407 } else if (op_name.equals_insensitive("BGEZAL") || 1408 op_name.equals_insensitive("BGEZALL")) { 1409 if (rs_val >= 0) 1410 target = pc + offset; 1411 else 1412 target = pc + 8; 1413 } 1414 1415 Context context; 1416 1417 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1418 target)) 1419 return false; 1420 1421 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1422 pc + 8)) 1423 return false; 1424 1425 return true; 1426 } 1427 1428 bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) { 1429 bool success = false; 1430 int64_t offset, pc, target; 1431 1432 /* 1433 * BAL offset 1434 * offset = sign_ext (offset << 2) 1435 * RA = PC + 8 1436 * PC = PC + offset 1437 */ 1438 offset = insn.getOperand(0).getImm(); 1439 1440 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1441 if (!success) 1442 return false; 1443 1444 target = pc + offset; 1445 1446 Context context; 1447 1448 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1449 target)) 1450 return false; 1451 1452 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1453 pc + 8)) 1454 return false; 1455 1456 return true; 1457 } 1458 1459 bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) { 1460 bool success = false; 1461 int64_t offset, pc, target; 1462 1463 /* 1464 * BALC offset 1465 * offset = sign_ext (offset << 2) 1466 * RA = PC + 4 1467 * PC = PC + 4 + offset 1468 */ 1469 offset = insn.getOperand(0).getImm(); 1470 1471 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1472 if (!success) 1473 return false; 1474 1475 target = pc + offset; 1476 1477 Context context; 1478 1479 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1480 target)) 1481 return false; 1482 1483 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1484 pc + 4)) 1485 return false; 1486 1487 return true; 1488 } 1489 1490 /* 1491 Emulate below MIPS conditional branch and link instructions. 1492 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches 1493 */ 1494 bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) { 1495 bool success = false; 1496 uint32_t rs; 1497 int64_t offset, pc, rs_val, target = 0; 1498 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1499 1500 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1501 offset = insn.getOperand(1).getImm(); 1502 1503 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1504 if (!success) 1505 return false; 1506 1507 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1508 dwarf_zero_mips64 + rs, 0, &success); 1509 if (!success) 1510 return false; 1511 1512 if (op_name.equals_insensitive("BLEZALC")) { 1513 if (rs_val <= 0) 1514 target = pc + offset; 1515 else 1516 target = pc + 4; 1517 } else if (op_name.equals_insensitive("BGEZALC")) { 1518 if (rs_val >= 0) 1519 target = pc + offset; 1520 else 1521 target = pc + 4; 1522 } else if (op_name.equals_insensitive("BLTZALC")) { 1523 if (rs_val < 0) 1524 target = pc + offset; 1525 else 1526 target = pc + 4; 1527 } else if (op_name.equals_insensitive("BGTZALC")) { 1528 if (rs_val > 0) 1529 target = pc + offset; 1530 else 1531 target = pc + 4; 1532 } else if (op_name.equals_insensitive("BEQZALC")) { 1533 if (rs_val == 0) 1534 target = pc + offset; 1535 else 1536 target = pc + 4; 1537 } else if (op_name.equals_insensitive("BNEZALC")) { 1538 if (rs_val != 0) 1539 target = pc + offset; 1540 else 1541 target = pc + 4; 1542 } 1543 1544 Context context; 1545 1546 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1547 target)) 1548 return false; 1549 1550 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1551 pc + 4)) 1552 return false; 1553 1554 return true; 1555 } 1556 1557 /* 1558 Emulate below MIPS branch instructions. 1559 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely 1560 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches 1561 */ 1562 bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) { 1563 bool success = false; 1564 uint32_t rs; 1565 int64_t offset, pc, rs_val, target = 0; 1566 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1567 1568 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1569 offset = insn.getOperand(1).getImm(); 1570 1571 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1572 if (!success) 1573 return false; 1574 1575 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1576 dwarf_zero_mips64 + rs, 0, &success); 1577 if (!success) 1578 return false; 1579 1580 if (op_name.equals_insensitive("BLTZL") || 1581 op_name.equals_insensitive("BLTZ") || 1582 op_name.equals_insensitive("BLTZ64")) { 1583 if (rs_val < 0) 1584 target = pc + offset; 1585 else 1586 target = pc + 8; 1587 } else if (op_name.equals_insensitive("BGEZL") || 1588 op_name.equals_insensitive("BGEZ") || 1589 op_name.equals_insensitive("BGEZ64")) { 1590 if (rs_val >= 0) 1591 target = pc + offset; 1592 else 1593 target = pc + 8; 1594 } else if (op_name.equals_insensitive("BGTZL") || 1595 op_name.equals_insensitive("BGTZ") || 1596 op_name.equals_insensitive("BGTZ64")) { 1597 if (rs_val > 0) 1598 target = pc + offset; 1599 else 1600 target = pc + 8; 1601 } else if (op_name.equals_insensitive("BLEZL") || 1602 op_name.equals_insensitive("BLEZ") || 1603 op_name.equals_insensitive("BLEZ64")) { 1604 if (rs_val <= 0) 1605 target = pc + offset; 1606 else 1607 target = pc + 8; 1608 } 1609 1610 Context context; 1611 context.type = eContextRelativeBranchImmediate; 1612 context.SetImmediate(offset); 1613 1614 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1615 target); 1616 } 1617 1618 bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) { 1619 bool success = false; 1620 int64_t offset, pc, target; 1621 1622 /* 1623 * BC offset 1624 * offset = sign_ext (offset << 2) 1625 * PC = PC + 4 + offset 1626 */ 1627 offset = insn.getOperand(0).getImm(); 1628 1629 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1630 if (!success) 1631 return false; 1632 1633 target = pc + offset; 1634 1635 Context context; 1636 1637 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1638 target); 1639 } 1640 1641 static int IsAdd64bitOverflow(int64_t a, int64_t b) { 1642 int64_t r = (uint64_t)a + (uint64_t)b; 1643 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0); 1644 } 1645 1646 /* 1647 Emulate below MIPS branch instructions. 1648 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch 1649 instructions with no delay slot 1650 */ 1651 bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) { 1652 bool success = false; 1653 uint32_t rs, rt; 1654 int64_t offset, pc, rs_val, rt_val, target = 0; 1655 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1656 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1657 1658 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1659 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1660 offset = insn.getOperand(2).getImm(); 1661 1662 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1663 if (!success) 1664 return false; 1665 1666 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1667 dwarf_zero_mips64 + rs, 0, &success); 1668 if (!success) 1669 return false; 1670 1671 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1672 dwarf_zero_mips64 + rt, 0, &success); 1673 if (!success) 1674 return false; 1675 1676 if (op_name.equals_insensitive("BEQC") || 1677 op_name.equals_insensitive("BEQC64")) { 1678 if (rs_val == rt_val) 1679 target = pc + offset; 1680 else 1681 target = pc + 4; 1682 } else if (op_name.equals_insensitive("BNEC") || 1683 op_name.equals_insensitive("BNEC64")) { 1684 if (rs_val != rt_val) 1685 target = pc + offset; 1686 else 1687 target = pc + 4; 1688 } else if (op_name.equals_insensitive("BLTC") || 1689 op_name.equals_insensitive("BLTC64")) { 1690 if (rs_val < rt_val) 1691 target = pc + offset; 1692 else 1693 target = pc + 4; 1694 } else if (op_name.equals_insensitive("BGEC64") || 1695 op_name.equals_insensitive("BGEC")) { 1696 if (rs_val >= rt_val) 1697 target = pc + offset; 1698 else 1699 target = pc + 4; 1700 } else if (op_name.equals_insensitive("BLTUC") || 1701 op_name.equals_insensitive("BLTUC64")) { 1702 if (rs_val < rt_val) 1703 target = pc + offset; 1704 else 1705 target = pc + 4; 1706 } else if (op_name.equals_insensitive("BGEUC") || 1707 op_name.equals_insensitive("BGEUC64")) { 1708 if ((uint32_t)rs_val >= (uint32_t)rt_val) 1709 target = pc + offset; 1710 else 1711 target = pc + 4; 1712 } else if (op_name.equals_insensitive("BOVC")) { 1713 if (IsAdd64bitOverflow(rs_val, rt_val)) 1714 target = pc + offset; 1715 else 1716 target = pc + 4; 1717 } else if (op_name.equals_insensitive("BNVC")) { 1718 if (!IsAdd64bitOverflow(rs_val, rt_val)) 1719 target = pc + offset; 1720 else 1721 target = pc + 4; 1722 } 1723 1724 Context context; 1725 context.type = eContextRelativeBranchImmediate; 1726 context.SetImmediate(current_inst_size + offset); 1727 1728 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1729 target); 1730 } 1731 1732 /* 1733 Emulate below MIPS branch instructions. 1734 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches 1735 */ 1736 bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) { 1737 bool success = false; 1738 uint32_t rs; 1739 int64_t offset, pc, target = 0; 1740 int64_t rs_val; 1741 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1742 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1743 1744 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1745 offset = insn.getOperand(1).getImm(); 1746 1747 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1748 if (!success) 1749 return false; 1750 1751 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1752 dwarf_zero_mips64 + rs, 0, &success); 1753 if (!success) 1754 return false; 1755 1756 if (op_name.equals_insensitive("BLTZC") || 1757 op_name.equals_insensitive("BLTZC64")) { 1758 if (rs_val < 0) 1759 target = pc + offset; 1760 else 1761 target = pc + 4; 1762 } else if (op_name.equals_insensitive("BLEZC") || 1763 op_name.equals_insensitive("BLEZC64")) { 1764 if (rs_val <= 0) 1765 target = pc + offset; 1766 else 1767 target = pc + 4; 1768 } else if (op_name.equals_insensitive("BGEZC") || 1769 op_name.equals_insensitive("BGEZC64")) { 1770 if (rs_val >= 0) 1771 target = pc + offset; 1772 else 1773 target = pc + 4; 1774 } else if (op_name.equals_insensitive("BGTZC") || 1775 op_name.equals_insensitive("BGTZC64")) { 1776 if (rs_val > 0) 1777 target = pc + offset; 1778 else 1779 target = pc + 4; 1780 } else if (op_name.equals_insensitive("BEQZC") || 1781 op_name.equals_insensitive("BEQZC64")) { 1782 if (rs_val == 0) 1783 target = pc + offset; 1784 else 1785 target = pc + 4; 1786 } else if (op_name.equals_insensitive("BNEZC") || 1787 op_name.equals_insensitive("BNEZC64")) { 1788 if (rs_val != 0) 1789 target = pc + offset; 1790 else 1791 target = pc + 4; 1792 } 1793 1794 Context context; 1795 context.type = eContextRelativeBranchImmediate; 1796 context.SetImmediate(current_inst_size + offset); 1797 1798 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1799 target); 1800 } 1801 1802 bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) { 1803 bool success = false; 1804 uint64_t offset, pc; 1805 1806 /* 1807 * J offset 1808 * offset = sign_ext (offset << 2) 1809 * PC = PC[63-28] | offset 1810 */ 1811 offset = insn.getOperand(0).getImm(); 1812 1813 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1814 if (!success) 1815 return false; 1816 1817 /* This is a PC-region branch and not PC-relative */ 1818 pc = (pc & 0xFFFFFFFFF0000000ULL) | offset; 1819 1820 Context context; 1821 1822 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1823 pc); 1824 } 1825 1826 bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) { 1827 bool success = false; 1828 uint64_t offset, target, pc; 1829 1830 /* 1831 * JAL offset 1832 * offset = sign_ext (offset << 2) 1833 * PC = PC[63-28] | offset 1834 */ 1835 offset = insn.getOperand(0).getImm(); 1836 1837 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1838 if (!success) 1839 return false; 1840 1841 /* This is a PC-region branch and not PC-relative */ 1842 target = (pc & 0xFFFFFFFFF0000000ULL) | offset; 1843 1844 Context context; 1845 1846 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1847 target)) 1848 return false; 1849 1850 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1851 pc + 8)) 1852 return false; 1853 1854 return true; 1855 } 1856 1857 bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) { 1858 bool success = false; 1859 uint32_t rs, rt; 1860 uint64_t pc, rs_val; 1861 1862 /* 1863 * JALR rt, rs 1864 * GPR[rt] = PC + 8 1865 * PC = GPR[rs] 1866 */ 1867 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1868 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1869 1870 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1871 if (!success) 1872 return false; 1873 1874 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, 1875 &success); 1876 if (!success) 1877 return false; 1878 1879 Context context; 1880 1881 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1882 rs_val)) 1883 return false; 1884 1885 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1886 dwarf_zero_mips64 + rt, pc + 8)) 1887 return false; 1888 1889 return true; 1890 } 1891 1892 bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) { 1893 bool success = false; 1894 uint32_t rt; 1895 int64_t target, offset, pc, rt_val; 1896 1897 /* 1898 * JIALC rt, offset 1899 * offset = sign_ext (offset) 1900 * PC = GPR[rt] + offset 1901 * RA = PC + 4 1902 */ 1903 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1904 offset = insn.getOperand(1).getImm(); 1905 1906 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1907 if (!success) 1908 return false; 1909 1910 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1911 dwarf_zero_mips64 + rt, 0, &success); 1912 if (!success) 1913 return false; 1914 1915 target = rt_val + offset; 1916 1917 Context context; 1918 1919 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1920 target)) 1921 return false; 1922 1923 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1924 pc + 4)) 1925 return false; 1926 1927 return true; 1928 } 1929 1930 bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) { 1931 bool success = false; 1932 uint32_t rt; 1933 int64_t target, offset, rt_val; 1934 1935 /* 1936 * JIC rt, offset 1937 * offset = sign_ext (offset) 1938 * PC = GPR[rt] + offset 1939 */ 1940 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1941 offset = insn.getOperand(1).getImm(); 1942 1943 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1944 dwarf_zero_mips64 + rt, 0, &success); 1945 if (!success) 1946 return false; 1947 1948 target = rt_val + offset; 1949 1950 Context context; 1951 1952 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1953 target); 1954 } 1955 1956 bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) { 1957 bool success = false; 1958 uint32_t rs; 1959 uint64_t rs_val; 1960 1961 /* 1962 * JR rs 1963 * PC = GPR[rs] 1964 */ 1965 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1966 1967 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, 1968 &success); 1969 if (!success) 1970 return false; 1971 1972 Context context; 1973 1974 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1975 rs_val); 1976 } 1977 1978 /* 1979 Emulate Branch on FP True/False 1980 BC1F, BC1FL : Branch on FP False (L stands for branch likely) 1981 BC1T, BC1TL : Branch on FP True (L stands for branch likely) 1982 */ 1983 bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) { 1984 bool success = false; 1985 uint32_t cc, fcsr; 1986 int64_t pc, offset, target = 0; 1987 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1988 1989 /* 1990 * BC1F cc, offset 1991 * condition <- (FPConditionCode(cc) == 0) 1992 * if condition then 1993 * offset = sign_ext (offset) 1994 * PC = PC + offset 1995 */ 1996 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1997 offset = insn.getOperand(1).getImm(); 1998 1999 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2000 if (!success) 2001 return false; 2002 2003 fcsr = 2004 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success); 2005 if (!success) 2006 return false; 2007 2008 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2009 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2010 2011 if (op_name.equals_insensitive("BC1F") || 2012 op_name.equals_insensitive("BC1FL")) { 2013 if ((fcsr & (1 << cc)) == 0) 2014 target = pc + offset; 2015 else 2016 target = pc + 8; 2017 } else if (op_name.equals_insensitive("BC1T") || 2018 op_name.equals_insensitive("BC1TL")) { 2019 if ((fcsr & (1 << cc)) != 0) 2020 target = pc + offset; 2021 else 2022 target = pc + 8; 2023 } 2024 2025 Context context; 2026 2027 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2028 target); 2029 } 2030 2031 bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) { 2032 bool success = false; 2033 uint32_t ft; 2034 uint64_t ft_val; 2035 int64_t target, pc, offset; 2036 2037 /* 2038 * BC1EQZ ft, offset 2039 * condition <- (FPR[ft].bit0 == 0) 2040 * if condition then 2041 * offset = sign_ext (offset) 2042 * PC = PC + 4 + offset 2043 */ 2044 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2045 offset = insn.getOperand(1).getImm(); 2046 2047 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2048 if (!success) 2049 return false; 2050 2051 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, 2052 &success); 2053 if (!success) 2054 return false; 2055 2056 if ((ft_val & 1) == 0) 2057 target = pc + 4 + offset; 2058 else 2059 target = pc + 8; 2060 2061 Context context; 2062 2063 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2064 target); 2065 } 2066 2067 bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) { 2068 bool success = false; 2069 uint32_t ft; 2070 uint64_t ft_val; 2071 int64_t target, pc, offset; 2072 2073 /* 2074 * BC1NEZ ft, offset 2075 * condition <- (FPR[ft].bit0 != 0) 2076 * if condition then 2077 * offset = sign_ext (offset) 2078 * PC = PC + 4 + offset 2079 */ 2080 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2081 offset = insn.getOperand(1).getImm(); 2082 2083 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2084 if (!success) 2085 return false; 2086 2087 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, 2088 &success); 2089 if (!success) 2090 return false; 2091 2092 if ((ft_val & 1) != 0) 2093 target = pc + 4 + offset; 2094 else 2095 target = pc + 8; 2096 2097 Context context; 2098 2099 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2100 target); 2101 } 2102 2103 /* 2104 Emulate MIPS-3D Branch instructions 2105 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes 2106 False/True 2107 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes 2108 False/True 2109 */ 2110 bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) { 2111 bool success = false; 2112 uint32_t cc, fcsr; 2113 int64_t pc, offset, target = 0; 2114 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2115 2116 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2117 offset = insn.getOperand(1).getImm(); 2118 2119 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2120 if (!success) 2121 return false; 2122 2123 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 2124 0, &success); 2125 if (!success) 2126 return false; 2127 2128 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2129 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2130 2131 if (op_name.equals_insensitive("BC1ANY2F")) { 2132 /* if any one bit is 0 */ 2133 if (((fcsr >> cc) & 3) != 3) 2134 target = pc + offset; 2135 else 2136 target = pc + 8; 2137 } else if (op_name.equals_insensitive("BC1ANY2T")) { 2138 /* if any one bit is 1 */ 2139 if (((fcsr >> cc) & 3) != 0) 2140 target = pc + offset; 2141 else 2142 target = pc + 8; 2143 } else if (op_name.equals_insensitive("BC1ANY4F")) { 2144 /* if any one bit is 0 */ 2145 if (((fcsr >> cc) & 0xf) != 0xf) 2146 target = pc + offset; 2147 else 2148 target = pc + 8; 2149 } else if (op_name.equals_insensitive("BC1ANY4T")) { 2150 /* if any one bit is 1 */ 2151 if (((fcsr >> cc) & 0xf) != 0) 2152 target = pc + offset; 2153 else 2154 target = pc + 8; 2155 } 2156 2157 Context context; 2158 2159 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2160 target); 2161 } 2162 2163 bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) { 2164 return Emulate_MSA_Branch_DF(insn, 1, true); 2165 } 2166 2167 bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) { 2168 return Emulate_MSA_Branch_DF(insn, 2, true); 2169 } 2170 2171 bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) { 2172 return Emulate_MSA_Branch_DF(insn, 4, true); 2173 } 2174 2175 bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) { 2176 return Emulate_MSA_Branch_DF(insn, 8, true); 2177 } 2178 2179 bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) { 2180 return Emulate_MSA_Branch_DF(insn, 1, false); 2181 } 2182 2183 bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) { 2184 return Emulate_MSA_Branch_DF(insn, 2, false); 2185 } 2186 2187 bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) { 2188 return Emulate_MSA_Branch_DF(insn, 4, false); 2189 } 2190 2191 bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) { 2192 return Emulate_MSA_Branch_DF(insn, 8, false); 2193 } 2194 2195 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn, 2196 int element_byte_size, 2197 bool bnz) { 2198 bool success = false, branch_hit = true; 2199 int64_t target = 0; 2200 RegisterValue reg_value; 2201 const uint8_t *ptr = nullptr; 2202 2203 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2204 int64_t offset = insn.getOperand(1).getImm(); 2205 2206 int64_t pc = 2207 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2208 if (!success) 2209 return false; 2210 2211 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value)) 2212 ptr = (const uint8_t *)reg_value.GetBytes(); 2213 else 2214 return false; 2215 2216 for (int i = 0; i < 16 / element_byte_size; i++) { 2217 switch (element_byte_size) { 2218 case 1: 2219 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz)) 2220 branch_hit = false; 2221 break; 2222 case 2: 2223 if ((*(const uint16_t *)ptr == 0 && bnz) || 2224 (*(const uint16_t *)ptr != 0 && !bnz)) 2225 branch_hit = false; 2226 break; 2227 case 4: 2228 if ((*(const uint32_t *)ptr == 0 && bnz) || 2229 (*(const uint32_t *)ptr != 0 && !bnz)) 2230 branch_hit = false; 2231 break; 2232 case 8: 2233 if ((*(const uint64_t *)ptr == 0 && bnz) || 2234 (*(const uint64_t *)ptr != 0 && !bnz)) 2235 branch_hit = false; 2236 break; 2237 } 2238 if (!branch_hit) 2239 break; 2240 ptr = ptr + element_byte_size; 2241 } 2242 2243 if (branch_hit) 2244 target = pc + offset; 2245 else 2246 target = pc + 8; 2247 2248 Context context; 2249 context.type = eContextRelativeBranchImmediate; 2250 2251 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2252 target); 2253 } 2254 2255 bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) { 2256 return Emulate_MSA_Branch_V(insn, true); 2257 } 2258 2259 bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) { 2260 return Emulate_MSA_Branch_V(insn, false); 2261 } 2262 2263 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn, 2264 bool bnz) { 2265 bool success = false; 2266 int64_t target = 0; 2267 llvm::APInt wr_val = llvm::APInt::getZero(128); 2268 llvm::APInt fail_value = llvm::APInt::getMaxValue(128); 2269 llvm::APInt zero_value = llvm::APInt::getZero(128); 2270 RegisterValue reg_value; 2271 2272 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2273 int64_t offset = insn.getOperand(1).getImm(); 2274 2275 int64_t pc = 2276 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2277 if (!success) 2278 return false; 2279 2280 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value)) 2281 wr_val = reg_value.GetAsUInt128(fail_value); 2282 else 2283 return false; 2284 2285 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || 2286 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) 2287 target = pc + offset; 2288 else 2289 target = pc + 8; 2290 2291 Context context; 2292 context.type = eContextRelativeBranchImmediate; 2293 2294 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2295 target); 2296 } 2297 2298 bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) { 2299 bool success = false; 2300 uint32_t base; 2301 int64_t imm, address; 2302 Context bad_vaddr_context; 2303 2304 uint32_t num_operands = insn.getNumOperands(); 2305 base = 2306 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 2307 imm = insn.getOperand(num_operands - 1).getImm(); 2308 2309 RegisterInfo reg_info_base; 2310 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 2311 reg_info_base)) 2312 return false; 2313 2314 /* read base register */ 2315 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, 2316 &success); 2317 if (!success) 2318 return false; 2319 2320 /* destination address */ 2321 address = address + imm; 2322 2323 /* Set the bad_vaddr register with base address used in the instruction */ 2324 bad_vaddr_context.type = eContextInvalid; 2325 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 2326 address); 2327 2328 return true; 2329 } 2330 2331 bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) { 2332 bool success = false; 2333 uint32_t base, index; 2334 int64_t address, index_address; 2335 Context bad_vaddr_context; 2336 2337 uint32_t num_operands = insn.getNumOperands(); 2338 base = 2339 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 2340 index = 2341 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg()); 2342 2343 RegisterInfo reg_info_base, reg_info_index; 2344 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 2345 reg_info_base)) 2346 return false; 2347 2348 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index, 2349 reg_info_index)) 2350 return false; 2351 2352 /* read base register */ 2353 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, 2354 &success); 2355 if (!success) 2356 return false; 2357 2358 /* read index register */ 2359 index_address = ReadRegisterUnsigned(eRegisterKindDWARF, 2360 dwarf_zero_mips + index, 0, &success); 2361 if (!success) 2362 return false; 2363 2364 /* destination address */ 2365 address = address + index_address; 2366 2367 /* Set the bad_vaddr register with base address used in the instruction */ 2368 bad_vaddr_context.type = eContextInvalid; 2369 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 2370 address); 2371 2372 return true; 2373 } 2374