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