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