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