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