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