1 //===-- EmulateInstructionMIPS64.cpp -----------------------------*- C++-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "EmulateInstructionMIPS64.h"
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/Host/PosixApi.h"
19 #include "lldb/Symbol/UnwindPlan.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"
35 #include "llvm/ADT/STLExtras.h"
37 #include "Plugins/Process/Utility/InstructionUtils.h"
38 #include "Plugins/Process/Utility/RegisterContext_mips.h"
41 using namespace lldb_private;
43 #define UInt(x) ((uint64_t)x)
44 #define integer int64_t
46 //----------------------------------------------------------------------
48 // EmulateInstructionMIPS64 implementation
50 //----------------------------------------------------------------------
54 void LLVMInitializeMipsTargetInfo();
55 void LLVMInitializeMipsTarget();
56 void LLVMInitializeMipsAsmPrinter();
57 void LLVMInitializeMipsTargetMC();
58 void LLVMInitializeMipsDisassembler();
62 EmulateInstructionMIPS64::EmulateInstructionMIPS64(
63 const lldb_private::ArchSpec &arch)
64 : EmulateInstruction(arch) {
65 /* Create instance of llvm::MCDisassembler */
67 llvm::Triple triple = arch.GetTriple();
68 const llvm::Target *target =
69 llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
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
76 * to decode the instructions so that the decoding complexity stays with LLVM.
77 * Initialize the MIPS targets and disassemblers.
81 LLVMInitializeMipsTargetInfo();
82 LLVMInitializeMipsTarget();
83 LLVMInitializeMipsAsmPrinter();
84 LLVMInitializeMipsTargetMC();
85 LLVMInitializeMipsDisassembler();
86 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
94 switch (arch.GetCore()) {
95 case ArchSpec::eCore_mips32:
96 case ArchSpec::eCore_mips32el:
99 case ArchSpec::eCore_mips32r2:
100 case ArchSpec::eCore_mips32r2el:
103 case ArchSpec::eCore_mips32r3:
104 case ArchSpec::eCore_mips32r3el:
107 case ArchSpec::eCore_mips32r5:
108 case ArchSpec::eCore_mips32r5el:
111 case ArchSpec::eCore_mips32r6:
112 case ArchSpec::eCore_mips32r6el:
115 case ArchSpec::eCore_mips64:
116 case ArchSpec::eCore_mips64el:
119 case ArchSpec::eCore_mips64r2:
120 case ArchSpec::eCore_mips64r2el:
123 case ArchSpec::eCore_mips64r3:
124 case ArchSpec::eCore_mips64r3el:
127 case ArchSpec::eCore_mips64r5:
128 case ArchSpec::eCore_mips64r5el:
131 case ArchSpec::eCore_mips64r6:
132 case ArchSpec::eCore_mips64r6el:
140 std::string features = "";
141 uint32_t arch_flags = arch.GetFlags();
142 if (arch_flags & ArchSpec::eMIPSAse_msa)
144 if (arch_flags & ArchSpec::eMIPSAse_dsp)
146 if (arch_flags & ArchSpec::eMIPSAse_dspr2)
147 features += "+dspr2,";
148 if (arch_flags & ArchSpec::eMIPSAse_mips16)
149 features += "+mips16,";
150 if (arch_flags & ArchSpec::eMIPSAse_micromips)
151 features += "+micromips,";
153 m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
154 assert(m_reg_info.get());
156 m_insn_info.reset(target->createMCInstrInfo());
157 assert(m_insn_info.get());
159 m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
160 m_subtype_info.reset(
161 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
162 assert(m_asm_info.get() && m_subtype_info.get());
165 new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
166 assert(m_context.get());
168 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
169 assert(m_disasm.get());
172 void EmulateInstructionMIPS64::Initialize() {
173 PluginManager::RegisterPlugin(GetPluginNameStatic(),
174 GetPluginDescriptionStatic(), CreateInstance);
177 void EmulateInstructionMIPS64::Terminate() {
178 PluginManager::UnregisterPlugin(CreateInstance);
181 ConstString EmulateInstructionMIPS64::GetPluginNameStatic() {
182 ConstString g_plugin_name("lldb.emulate-instruction.mips64");
183 return g_plugin_name;
186 lldb_private::ConstString EmulateInstructionMIPS64::GetPluginName() {
187 static ConstString g_plugin_name("EmulateInstructionMIPS64");
188 return g_plugin_name;
191 const char *EmulateInstructionMIPS64::GetPluginDescriptionStatic() {
192 return "Emulate instructions for the MIPS64 architecture.";
196 EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
197 InstructionType inst_type) {
198 if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(
200 if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
201 arch.GetTriple().getArch() == llvm::Triple::mips64el) {
202 return new EmulateInstructionMIPS64(arch);
209 bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) {
210 if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
211 arch.GetTriple().getArch() == llvm::Triple::mips64el)
216 const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num,
217 bool alternate_name) {
218 if (alternate_name) {
220 case dwarf_sp_mips64:
222 case dwarf_r30_mips64:
224 case dwarf_ra_mips64:
226 case dwarf_f0_mips64:
228 case dwarf_f1_mips64:
230 case dwarf_f2_mips64:
232 case dwarf_f3_mips64:
234 case dwarf_f4_mips64:
236 case dwarf_f5_mips64:
238 case dwarf_f6_mips64:
240 case dwarf_f7_mips64:
242 case dwarf_f8_mips64:
244 case dwarf_f9_mips64:
246 case dwarf_f10_mips64:
248 case dwarf_f11_mips64:
250 case dwarf_f12_mips64:
252 case dwarf_f13_mips64:
254 case dwarf_f14_mips64:
256 case dwarf_f15_mips64:
258 case dwarf_f16_mips64:
260 case dwarf_f17_mips64:
262 case dwarf_f18_mips64:
264 case dwarf_f19_mips64:
266 case dwarf_f20_mips64:
268 case dwarf_f21_mips64:
270 case dwarf_f22_mips64:
272 case dwarf_f23_mips64:
274 case dwarf_f24_mips64:
276 case dwarf_f25_mips64:
278 case dwarf_f26_mips64:
280 case dwarf_f27_mips64:
282 case dwarf_f28_mips64:
284 case dwarf_f29_mips64:
286 case dwarf_f30_mips64:
288 case dwarf_f31_mips64:
290 case dwarf_w0_mips64:
292 case dwarf_w1_mips64:
294 case dwarf_w2_mips64:
296 case dwarf_w3_mips64:
298 case dwarf_w4_mips64:
300 case dwarf_w5_mips64:
302 case dwarf_w6_mips64:
304 case dwarf_w7_mips64:
306 case dwarf_w8_mips64:
308 case dwarf_w9_mips64:
310 case dwarf_w10_mips64:
312 case dwarf_w11_mips64:
314 case dwarf_w12_mips64:
316 case dwarf_w13_mips64:
318 case dwarf_w14_mips64:
320 case dwarf_w15_mips64:
322 case dwarf_w16_mips64:
324 case dwarf_w17_mips64:
326 case dwarf_w18_mips64:
328 case dwarf_w19_mips64:
330 case dwarf_w20_mips64:
332 case dwarf_w21_mips64:
334 case dwarf_w22_mips64:
336 case dwarf_w23_mips64:
338 case dwarf_w24_mips64:
340 case dwarf_w25_mips64:
342 case dwarf_w26_mips64:
344 case dwarf_w27_mips64:
346 case dwarf_w28_mips64:
348 case dwarf_w29_mips64:
350 case dwarf_w30_mips64:
352 case dwarf_w31_mips64:
354 case dwarf_mir_mips64:
356 case dwarf_mcsr_mips64:
358 case dwarf_config5_mips64:
367 case dwarf_zero_mips64:
369 case dwarf_r1_mips64:
371 case dwarf_r2_mips64:
373 case dwarf_r3_mips64:
375 case dwarf_r4_mips64:
377 case dwarf_r5_mips64:
379 case dwarf_r6_mips64:
381 case dwarf_r7_mips64:
383 case dwarf_r8_mips64:
385 case dwarf_r9_mips64:
387 case dwarf_r10_mips64:
389 case dwarf_r11_mips64:
391 case dwarf_r12_mips64:
393 case dwarf_r13_mips64:
395 case dwarf_r14_mips64:
397 case dwarf_r15_mips64:
399 case dwarf_r16_mips64:
401 case dwarf_r17_mips64:
403 case dwarf_r18_mips64:
405 case dwarf_r19_mips64:
407 case dwarf_r20_mips64:
409 case dwarf_r21_mips64:
411 case dwarf_r22_mips64:
413 case dwarf_r23_mips64:
415 case dwarf_r24_mips64:
417 case dwarf_r25_mips64:
419 case dwarf_r26_mips64:
421 case dwarf_r27_mips64:
423 case dwarf_gp_mips64:
425 case dwarf_sp_mips64:
427 case dwarf_r30_mips64:
429 case dwarf_ra_mips64:
431 case dwarf_sr_mips64:
433 case dwarf_lo_mips64:
435 case dwarf_hi_mips64:
437 case dwarf_bad_mips64:
439 case dwarf_cause_mips64:
441 case dwarf_pc_mips64:
443 case dwarf_f0_mips64:
445 case dwarf_f1_mips64:
447 case dwarf_f2_mips64:
449 case dwarf_f3_mips64:
451 case dwarf_f4_mips64:
453 case dwarf_f5_mips64:
455 case dwarf_f6_mips64:
457 case dwarf_f7_mips64:
459 case dwarf_f8_mips64:
461 case dwarf_f9_mips64:
463 case dwarf_f10_mips64:
465 case dwarf_f11_mips64:
467 case dwarf_f12_mips64:
469 case dwarf_f13_mips64:
471 case dwarf_f14_mips64:
473 case dwarf_f15_mips64:
475 case dwarf_f16_mips64:
477 case dwarf_f17_mips64:
479 case dwarf_f18_mips64:
481 case dwarf_f19_mips64:
483 case dwarf_f20_mips64:
485 case dwarf_f21_mips64:
487 case dwarf_f22_mips64:
489 case dwarf_f23_mips64:
491 case dwarf_f24_mips64:
493 case dwarf_f25_mips64:
495 case dwarf_f26_mips64:
497 case dwarf_f27_mips64:
499 case dwarf_f28_mips64:
501 case dwarf_f29_mips64:
503 case dwarf_f30_mips64:
505 case dwarf_f31_mips64:
507 case dwarf_fcsr_mips64:
509 case dwarf_fir_mips64:
511 case dwarf_w0_mips64:
513 case dwarf_w1_mips64:
515 case dwarf_w2_mips64:
517 case dwarf_w3_mips64:
519 case dwarf_w4_mips64:
521 case dwarf_w5_mips64:
523 case dwarf_w6_mips64:
525 case dwarf_w7_mips64:
527 case dwarf_w8_mips64:
529 case dwarf_w9_mips64:
531 case dwarf_w10_mips64:
533 case dwarf_w11_mips64:
535 case dwarf_w12_mips64:
537 case dwarf_w13_mips64:
539 case dwarf_w14_mips64:
541 case dwarf_w15_mips64:
543 case dwarf_w16_mips64:
545 case dwarf_w17_mips64:
547 case dwarf_w18_mips64:
549 case dwarf_w19_mips64:
551 case dwarf_w20_mips64:
553 case dwarf_w21_mips64:
555 case dwarf_w22_mips64:
557 case dwarf_w23_mips64:
559 case dwarf_w24_mips64:
561 case dwarf_w25_mips64:
563 case dwarf_w26_mips64:
565 case dwarf_w27_mips64:
567 case dwarf_w28_mips64:
569 case dwarf_w29_mips64:
571 case dwarf_w30_mips64:
573 case dwarf_w31_mips64:
575 case dwarf_mcsr_mips64:
577 case dwarf_mir_mips64:
579 case dwarf_config5_mips64:
585 bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind,
587 RegisterInfo ®_info) {
588 if (reg_kind == eRegisterKindGeneric) {
590 case LLDB_REGNUM_GENERIC_PC:
591 reg_kind = eRegisterKindDWARF;
592 reg_num = dwarf_pc_mips64;
594 case LLDB_REGNUM_GENERIC_SP:
595 reg_kind = eRegisterKindDWARF;
596 reg_num = dwarf_sp_mips64;
598 case LLDB_REGNUM_GENERIC_FP:
599 reg_kind = eRegisterKindDWARF;
600 reg_num = dwarf_r30_mips64;
602 case LLDB_REGNUM_GENERIC_RA:
603 reg_kind = eRegisterKindDWARF;
604 reg_num = dwarf_ra_mips64;
606 case LLDB_REGNUM_GENERIC_FLAGS:
607 reg_kind = eRegisterKindDWARF;
608 reg_num = dwarf_sr_mips64;
615 if (reg_kind == eRegisterKindDWARF) {
616 ::memset(®_info, 0, sizeof(RegisterInfo));
617 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
619 if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 ||
620 reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 ||
621 reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) {
622 reg_info.byte_size = 4;
623 reg_info.format = eFormatHex;
624 reg_info.encoding = eEncodingUint;
625 } else if ((int)reg_num >= dwarf_zero_mips64 &&
626 (int)reg_num <= dwarf_f31_mips64) {
627 reg_info.byte_size = 8;
628 reg_info.format = eFormatHex;
629 reg_info.encoding = eEncodingUint;
630 } else if ((int)reg_num >= dwarf_w0_mips64 &&
631 (int)reg_num <= dwarf_w31_mips64) {
632 reg_info.byte_size = 16;
633 reg_info.format = eFormatVectorOfUInt8;
634 reg_info.encoding = eEncodingVector;
639 reg_info.name = GetRegisterName(reg_num, false);
640 reg_info.alt_name = GetRegisterName(reg_num, true);
641 reg_info.kinds[eRegisterKindDWARF] = reg_num;
644 case dwarf_r30_mips64:
645 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
647 case dwarf_ra_mips64:
648 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
650 case dwarf_sp_mips64:
651 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
653 case dwarf_pc_mips64:
654 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
656 case dwarf_sr_mips64:
657 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
667 EmulateInstructionMIPS64::MipsOpcode *
668 EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
669 static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = {
670 //----------------------------------------------------------------------
671 // Prologue/Epilogue instructions
672 //----------------------------------------------------------------------
673 {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
674 "DADDIU rt, rs, immediate"},
675 {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
676 "ADDIU rt, rs, immediate"},
677 {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)"},
678 {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)"},
679 {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
681 {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
683 {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
685 {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
687 {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate"},
689 //----------------------------------------------------------------------
690 // Load/Store instructions
691 //----------------------------------------------------------------------
692 /* Following list of emulated instructions are required by implementation
693 of hardware watchpoint
694 for MIPS in lldb. As we just need the address accessed by instructions,
696 all these instructions in 2 functions depending on their addressing
699 {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
700 "LB rt, offset(base)"},
701 {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
702 "LBE rt, offset(base)"},
703 {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
704 "LBU rt, offset(base)"},
705 {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
706 "LBUE rt, offset(base)"},
707 {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
708 "LDC1 ft, offset(base)"},
709 {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
710 "LDL rt, offset(base)"},
711 {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
712 "LDR rt, offset(base)"},
713 {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
714 "LLD rt, offset(base)"},
715 {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
716 "LDC2 rt, offset(base)"},
717 {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
718 "LDXC1 fd, index (base)"},
719 {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
720 "LH rt, offset(base)"},
721 {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
722 "LHE rt, offset(base)"},
723 {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
724 "LHU rt, offset(base)"},
725 {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
726 "LHUE rt, offset(base)"},
727 {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
728 "LL rt, offset(base)"},
729 {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
730 "LLE rt, offset(base)"},
731 {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
732 "LUXC1 fd, index (base)"},
733 {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
734 "LW rt, offset(rs)"},
735 {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
736 "LWC1 ft, offset(base)"},
737 {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
738 "LWC2 rt, offset(base)"},
739 {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
740 "LWE rt, offset(base)"},
741 {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
742 "LWL rt, offset(base)"},
743 {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
744 "LWLE rt, offset(base)"},
745 {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
746 "LWR rt, offset(base)"},
747 {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
748 "LWRE rt, offset(base)"},
749 {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
750 "LWXC1 fd, index (base)"},
752 {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
753 "SB rt, offset(base)"},
754 {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
755 "SBE rt, offset(base)"},
756 {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
757 "SC rt, offset(base)"},
758 {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
759 "SCE rt, offset(base)"},
760 {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
761 "SCD rt, offset(base)"},
762 {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
763 "SDL rt, offset(base)"},
764 {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
765 "SDR rt, offset(base)"},
766 {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
767 "SDC1 ft, offset(base)"},
768 {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
769 "SDC2 rt, offset(base)"},
770 {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
771 "SDXC1 fs, index (base)"},
772 {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
773 "SH rt, offset(base)"},
774 {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
775 "SHE rt, offset(base)"},
776 {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
777 "SUXC1 fs, index (base)"},
778 {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
779 "SW rt, offset(rs)"},
780 {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
781 "SWC1 ft, offset(base)"},
782 {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
783 "SWC2 rt, offset(base)"},
784 {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
785 "SWE rt, offset(base)"},
786 {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
787 "SWL rt, offset(base)"},
788 {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
789 "SWLE rt, offset(base)"},
790 {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
791 "SWR rt, offset(base)"},
792 {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
793 "SWRE rt, offset(base)"},
794 {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
795 "SWXC1 fs, index (base)"},
797 //----------------------------------------------------------------------
798 // Branch instructions
799 //----------------------------------------------------------------------
800 {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
801 {"BEQ64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
802 {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
803 {"BNE64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
804 {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
805 "BEQL rs,rt,offset"},
806 {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
807 "BNEL rs,rt,offset"},
808 {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
809 "BGEZALL rt,offset"},
810 {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"},
811 {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
813 {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"},
814 {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"},
815 {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
816 {"BGEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
817 {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
818 "BLEZALC rs,offset"},
819 {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
820 "BGEZALC rs,offset"},
821 {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
822 "BLTZALC rs,offset"},
823 {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
824 "BGTZALC rs,offset"},
825 {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
826 "BEQZALC rs,offset"},
827 {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
828 "BNEZALC rs,offset"},
829 {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
830 "BEQC rs,rt,offset"},
831 {"BEQC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
832 "BEQC rs,rt,offset"},
833 {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
834 "BNEC rs,rt,offset"},
835 {"BNEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
836 "BNEC rs,rt,offset"},
837 {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
838 "BLTC rs,rt,offset"},
839 {"BLTC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
840 "BLTC rs,rt,offset"},
841 {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
842 "BGEC rs,rt,offset"},
843 {"BGEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
844 "BGEC rs,rt,offset"},
845 {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
846 "BLTUC rs,rt,offset"},
847 {"BLTUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
848 "BLTUC rs,rt,offset"},
849 {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
850 "BGEUC rs,rt,offset"},
851 {"BGEUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
852 "BGEUC rs,rt,offset"},
853 {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
855 {"BLTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
857 {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
859 {"BLEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
861 {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
863 {"BGEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
865 {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
867 {"BGTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
869 {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
871 {"BEQZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
873 {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
875 {"BNEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
877 {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"},
878 {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
879 {"BGTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
880 {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"},
881 {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
882 {"BLEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
883 {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"},
884 {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
885 {"BLTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
886 {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
888 {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
889 "BLTZALL rt,offset"},
890 {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"},
891 {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
892 "BOVC rs,rt,offset"},
893 {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
894 "BNVC rs,rt,offset"},
895 {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"},
896 {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"},
897 {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"},
898 {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
899 {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
900 {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"},
901 {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
902 {"JIALC64", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
903 {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
904 {"JIC64", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
905 {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
906 {"JR64", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
907 {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"},
908 {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"},
909 {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"},
910 {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch,
912 {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch,
914 {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ,
915 "BC1EQZ ft, offset"},
916 {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ,
917 "BC1NEZ ft, offset"},
918 {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch,
919 "BC1ANY2F cc, offset"},
920 {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch,
921 "BC1ANY2T cc, offset"},
922 {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch,
923 "BC1ANY4F cc, offset"},
924 {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch,
925 "BC1ANY4T cc, offset"},
926 {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"},
927 {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"},
928 {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"},
929 {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"},
930 {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"},
931 {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"},
932 {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"},
933 {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"},
934 {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"},
935 {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"},
938 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
940 for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
941 if (!strcasecmp(g_opcodes[i].op_name, op_name))
942 return &g_opcodes[i];
948 bool EmulateInstructionMIPS64::ReadInstruction() {
949 bool success = false;
950 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
951 LLDB_INVALID_ADDRESS, &success);
953 Context read_inst_context;
954 read_inst_context.type = eContextReadOpcode;
955 read_inst_context.SetNoArgs();
956 m_opcode.SetOpcode32(
957 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
961 m_addr = LLDB_INVALID_ADDRESS;
965 bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) {
966 bool success = false;
967 llvm::MCInst mc_insn;
971 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
973 if (m_opcode.GetData(data)) {
974 llvm::MCDisassembler::DecodeStatus decode_status;
975 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
976 decode_status = m_disasm->getInstruction(
977 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
978 if (decode_status != llvm::MCDisassembler::Success)
983 * mc_insn.getOpcode() returns decoded opcode. However to make use
984 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
986 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
992 * Decoding has been done already. Just get the call-back function
993 * and emulate the instruction.
995 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
997 if (opcode_data == NULL)
1000 uint64_t old_pc = 0, new_pc = 0;
1001 const bool auto_advance_pc =
1002 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1004 if (auto_advance_pc) {
1006 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1011 /* emulate instruction */
1012 success = (this->*opcode_data->callback)(mc_insn);
1016 if (auto_advance_pc) {
1018 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1022 /* If we haven't changed the PC, change it here */
1023 if (old_pc == new_pc) {
1026 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1035 bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
1036 UnwindPlan &unwind_plan) {
1037 unwind_plan.Clear();
1038 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1040 UnwindPlan::RowSP row(new UnwindPlan::Row);
1041 const bool can_replace = false;
1043 // Our previous Call Frame Address is the stack pointer
1044 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
1046 // Our previous PC is in the RA
1047 row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64,
1050 unwind_plan.AppendRow(row);
1052 // All other registers are the same.
1053 unwind_plan.SetSourceName("EmulateInstructionMIPS64");
1054 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1055 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1056 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
1061 bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) {
1063 case dwarf_r16_mips64:
1064 case dwarf_r17_mips64:
1065 case dwarf_r18_mips64:
1066 case dwarf_r19_mips64:
1067 case dwarf_r20_mips64:
1068 case dwarf_r21_mips64:
1069 case dwarf_r22_mips64:
1070 case dwarf_r23_mips64:
1071 case dwarf_gp_mips64:
1072 case dwarf_sp_mips64:
1073 case dwarf_r30_mips64:
1074 case dwarf_ra_mips64:
1082 bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
1083 // DADDIU rt, rs, immediate
1084 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1087 bool success = false;
1088 const uint32_t imm16 = insn.getOperand(2).getImm();
1089 int64_t imm = SignedBits(imm16, 15, 0);
1091 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1092 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1094 // If immediate is greater than 2^16 - 1 then clang generate
1095 // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
1098 // daddiu $1, $1, -0x5920
1099 // dsubu $sp, $sp, $1
1100 // In this case, (D)ADDIU dst and src will be same and not equal to sp
1104 /* read <src> register */
1105 const int64_t src_opd_val = ReadRegisterUnsigned(
1106 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1110 /* Check if this is daddiu sp, sp, imm16 */
1111 if (dst == dwarf_sp_mips64) {
1112 uint64_t result = src_opd_val + imm;
1113 RegisterInfo reg_info_sp;
1115 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1116 context.SetRegisterPlusOffset(reg_info_sp, imm);
1118 /* We are allocating bytes on stack */
1119 context.type = eContextAdjustStackPointer;
1121 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64,
1127 context.SetImmediateSigned(imm);
1128 context.type = eContextImmediate;
1130 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1131 dwarf_zero_mips64 + dst, imm))
1138 bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) {
1140 RegisterInfo reg_info_base;
1141 RegisterInfo reg_info_src;
1142 bool success = false;
1143 uint32_t imm16 = insn.getOperand(2).getImm();
1144 uint64_t imm = SignedBits(imm16, 15, 0);
1146 Context bad_vaddr_context;
1148 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1149 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1151 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1153 !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1158 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1163 /* destination address */
1164 address = address + imm;
1166 /* We look for sp based non-volatile register stores */
1167 if (nonvolatile_reg_p(src)) {
1169 RegisterValue data_src;
1170 context.type = eContextPushRegisterOnStack;
1171 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1173 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1176 if (!ReadRegister(®_info_base, data_src))
1179 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1180 eByteOrderLittle, error) == 0)
1183 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1187 /* Set the bad_vaddr register with base address used in the instruction */
1188 bad_vaddr_context.type = eContextInvalid;
1189 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1195 bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
1196 bool success = false;
1198 int64_t imm, address;
1199 Context bad_vaddr_context;
1201 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1202 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1203 imm = insn.getOperand(2).getImm();
1205 RegisterInfo reg_info_base;
1206 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1210 /* read base register */
1211 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1216 /* destination address */
1217 address = address + imm;
1219 /* Set the bad_vaddr register with base address used in the instruction */
1220 bad_vaddr_context.type = eContextInvalid;
1221 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1224 if (nonvolatile_reg_p(src)) {
1225 RegisterValue data_src;
1226 RegisterInfo reg_info_src;
1228 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1233 context.type = eContextRegisterLoad;
1235 if (!WriteRegister(context, ®_info_src, data_src))
1244 bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
1245 // LUI rt, immediate
1246 // GPR[rt] <- sign_extend(immediate << 16)
1248 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1249 int64_t imm = SignedBits(imm32, 31, 0);
1253 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1254 context.SetImmediateSigned(imm);
1255 context.type = eContextImmediate;
1257 if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips64 + rt,
1264 bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
1265 // DSUBU sp, <src>, <rt>
1266 // DADDU sp, <src>, <rt>
1267 // DADDU dst, sp, <rt>
1269 bool success = false;
1271 uint8_t src, dst, rt;
1272 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1274 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1275 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1277 /* Check if sp is destination register */
1278 if (dst == dwarf_sp_mips64) {
1279 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1281 /* read <src> register */
1282 uint64_t src_opd_val = ReadRegisterUnsigned(
1283 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1287 /* read <rt > register */
1288 uint64_t rt_opd_val = ReadRegisterUnsigned(
1289 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1293 if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
1294 result = src_opd_val - rt_opd_val;
1296 result = src_opd_val + rt_opd_val;
1299 RegisterInfo reg_info_sp;
1300 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1301 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1303 /* We are allocating bytes on stack */
1304 context.type = eContextAdjustStackPointer;
1306 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result);
1309 } else if (src == dwarf_sp_mips64) {
1310 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1312 /* read <src> register */
1313 uint64_t src_opd_val = ReadRegisterUnsigned(
1314 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1318 /* read <rt> register */
1319 uint64_t rt_opd_val = ReadRegisterUnsigned(
1320 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1326 if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
1327 result = src_opd_val - rt_opd_val;
1329 result = src_opd_val + rt_opd_val;
1331 context.SetImmediateSigned(result);
1332 context.type = eContextImmediate;
1334 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1335 dwarf_zero_mips64 + dst, result))
1343 Emulate below MIPS branch instructions.
1344 BEQ, BNE : Branch on condition
1345 BEQL, BNEL : Branch likely
1347 bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
1348 bool success = false;
1350 int64_t offset, pc, rs_val, rt_val, target = 0;
1351 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1353 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1354 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1355 offset = insn.getOperand(2).getImm();
1357 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1361 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1362 dwarf_zero_mips64 + rs, 0, &success);
1366 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1367 dwarf_zero_mips64 + rt, 0, &success);
1371 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")
1372 || !strcasecmp(op_name, "BEQ64") ) {
1373 if (rs_val == rt_val)
1374 target = pc + offset;
1377 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")
1378 || !strcasecmp(op_name, "BNE64")) {
1379 if (rs_val != rt_val)
1380 target = pc + offset;
1386 context.type = eContextRelativeBranchImmediate;
1387 context.SetImmediate(offset);
1389 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1397 Emulate below MIPS Non-Compact conditional branch and link instructions.
1399 BLTZALL, BGEZALL : Branch likely
1401 bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) {
1402 bool success = false;
1404 int64_t offset, pc, target = 0;
1406 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1408 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1409 offset = insn.getOperand(1).getImm();
1411 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1415 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1416 dwarf_zero_mips64 + rs, 0, &success);
1420 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
1422 target = pc + offset;
1425 } else if (!strcasecmp(op_name, "BGEZAL") ||
1426 !strcasecmp(op_name, "BGEZALL")) {
1428 target = pc + offset;
1435 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1439 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1446 bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) {
1447 bool success = false;
1448 int64_t offset, pc, target;
1452 * offset = sign_ext (offset << 2)
1456 offset = insn.getOperand(0).getImm();
1458 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1462 target = pc + offset;
1466 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1470 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1477 bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) {
1478 bool success = false;
1479 int64_t offset, pc, target;
1483 * offset = sign_ext (offset << 2)
1485 * PC = PC + 4 + offset
1487 offset = insn.getOperand(0).getImm();
1489 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1493 target = pc + offset;
1497 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1501 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1509 Emulate below MIPS conditional branch and link instructions.
1510 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1512 bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1513 bool success = false;
1515 int64_t offset, pc, rs_val, target = 0;
1516 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1518 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1519 offset = insn.getOperand(1).getImm();
1521 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1525 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1526 dwarf_zero_mips64 + rs, 0, &success);
1530 if (!strcasecmp(op_name, "BLEZALC")) {
1532 target = pc + offset;
1535 } else if (!strcasecmp(op_name, "BGEZALC")) {
1537 target = pc + offset;
1540 } else if (!strcasecmp(op_name, "BLTZALC")) {
1542 target = pc + offset;
1545 } else if (!strcasecmp(op_name, "BGTZALC")) {
1547 target = pc + offset;
1550 } else if (!strcasecmp(op_name, "BEQZALC")) {
1552 target = pc + offset;
1555 } else if (!strcasecmp(op_name, "BNEZALC")) {
1557 target = pc + offset;
1564 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1568 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1576 Emulate below MIPS branch instructions.
1577 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
1578 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
1580 bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
1581 bool success = false;
1583 int64_t offset, pc, rs_val, target = 0;
1584 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1586 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1587 offset = insn.getOperand(1).getImm();
1589 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1593 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1594 dwarf_zero_mips64 + rs, 0, &success);
1598 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")
1599 || !strcasecmp(op_name, "BLTZ64")) {
1601 target = pc + offset;
1604 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")
1605 || !strcasecmp(op_name, "BGEZ64")) {
1607 target = pc + offset;
1610 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")
1611 || !strcasecmp(op_name, "BGTZ64")) {
1613 target = pc + offset;
1616 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")
1617 || !strcasecmp(op_name, "BLEZ64")) {
1619 target = pc + offset;
1625 context.type = eContextRelativeBranchImmediate;
1626 context.SetImmediate(offset);
1628 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1635 bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
1636 bool success = false;
1637 int64_t offset, pc, target;
1641 * offset = sign_ext (offset << 2)
1642 * PC = PC + 4 + offset
1644 offset = insn.getOperand(0).getImm();
1646 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1650 target = pc + offset;
1654 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1661 static int IsAdd64bitOverflow(int64_t a, int64_t b) {
1662 int64_t r = (uint64_t)a + (uint64_t)b;
1663 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1667 Emulate below MIPS branch instructions.
1668 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1669 instructions with no delay slot
1671 bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1672 bool success = false;
1674 int64_t offset, pc, rs_val, rt_val, target = 0;
1675 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1676 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1678 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1679 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1680 offset = insn.getOperand(2).getImm();
1682 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1686 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1687 dwarf_zero_mips64 + rs, 0, &success);
1691 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1692 dwarf_zero_mips64 + rt, 0, &success);
1696 if (!strcasecmp(op_name, "BEQC") || !strcasecmp(op_name, "BEQC64")) {
1697 if (rs_val == rt_val)
1698 target = pc + offset;
1701 } else if (!strcasecmp(op_name, "BNEC") || !strcasecmp(op_name, "BNEC64")) {
1702 if (rs_val != rt_val)
1703 target = pc + offset;
1706 } else if (!strcasecmp(op_name, "BLTC") || !strcasecmp(op_name, "BLTC64")) {
1707 if (rs_val < rt_val)
1708 target = pc + offset;
1711 } else if (!strcasecmp(op_name, "BGEC64") || !strcasecmp(op_name, "BGEC")) {
1712 if (rs_val >= rt_val)
1713 target = pc + offset;
1716 } else if (!strcasecmp(op_name, "BLTUC") || !strcasecmp(op_name, "BLTUC64")) {
1717 if (rs_val < rt_val)
1718 target = pc + offset;
1721 } else if (!strcasecmp(op_name, "BGEUC") || !strcasecmp(op_name, "BGEUC64")) {
1722 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1723 target = pc + offset;
1726 } else if (!strcasecmp(op_name, "BOVC")) {
1727 if (IsAdd64bitOverflow(rs_val, rt_val))
1728 target = pc + offset;
1731 } else if (!strcasecmp(op_name, "BNVC")) {
1732 if (!IsAdd64bitOverflow(rs_val, rt_val))
1733 target = pc + offset;
1739 context.type = eContextRelativeBranchImmediate;
1740 context.SetImmediate(current_inst_size + offset);
1742 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1750 Emulate below MIPS branch instructions.
1751 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
1753 bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
1754 bool success = false;
1756 int64_t offset, pc, target = 0;
1758 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1759 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1761 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1762 offset = insn.getOperand(1).getImm();
1764 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1768 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1769 dwarf_zero_mips64 + rs, 0, &success);
1773 if (!strcasecmp(op_name, "BLTZC") || !strcasecmp(op_name, "BLTZC64")) {
1775 target = pc + offset;
1778 } else if (!strcasecmp(op_name, "BLEZC") || !strcasecmp(op_name, "BLEZC64")) {
1780 target = pc + offset;
1783 } else if (!strcasecmp(op_name, "BGEZC") || !strcasecmp(op_name, "BGEZC64")) {
1785 target = pc + offset;
1788 } else if (!strcasecmp(op_name, "BGTZC") || !strcasecmp(op_name, "BGTZC64")) {
1790 target = pc + offset;
1793 } else if (!strcasecmp(op_name, "BEQZC") || !strcasecmp(op_name, "BEQZC64")) {
1795 target = pc + offset;
1798 } else if (!strcasecmp(op_name, "BNEZC") || !strcasecmp(op_name, "BNEZC64")) {
1800 target = pc + offset;
1806 context.type = eContextRelativeBranchImmediate;
1807 context.SetImmediate(current_inst_size + offset);
1809 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1816 bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
1817 bool success = false;
1818 uint64_t offset, pc;
1822 * offset = sign_ext (offset << 2)
1823 * PC = PC[63-28] | offset
1825 offset = insn.getOperand(0).getImm();
1827 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1831 /* This is a PC-region branch and not PC-relative */
1832 pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1836 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
1842 bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
1843 bool success = false;
1844 uint64_t offset, target, pc;
1848 * offset = sign_ext (offset << 2)
1849 * PC = PC[63-28] | offset
1851 offset = insn.getOperand(0).getImm();
1853 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1857 /* This is a PC-region branch and not PC-relative */
1858 target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1862 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1866 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1873 bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) {
1874 bool success = false;
1876 uint64_t pc, rs_val;
1883 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1884 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1886 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1890 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1897 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1901 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1902 dwarf_zero_mips64 + rt, pc + 8))
1908 bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) {
1909 bool success = false;
1911 int64_t target, offset, pc, rt_val;
1915 * offset = sign_ext (offset)
1916 * PC = GPR[rt] + offset
1919 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1920 offset = insn.getOperand(1).getImm();
1922 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1926 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1927 dwarf_zero_mips64 + rt, 0, &success);
1931 target = rt_val + offset;
1935 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1939 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1946 bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
1947 bool success = false;
1949 int64_t target, offset, rt_val;
1953 * offset = sign_ext (offset)
1954 * PC = GPR[rt] + offset
1956 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1957 offset = insn.getOperand(1).getImm();
1959 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1960 dwarf_zero_mips64 + rt, 0, &success);
1964 target = rt_val + offset;
1968 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1975 bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
1976 bool success = false;
1984 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1986 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1993 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2001 Emulate Branch on FP True/False
2002 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2003 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2005 bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
2006 bool success = false;
2008 int64_t pc, offset, target = 0;
2009 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2013 * condition <- (FPConditionCode(cc) == 0)
2015 * offset = sign_ext (offset)
2018 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2019 offset = insn.getOperand(1).getImm();
2021 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2026 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
2030 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2031 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2033 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2034 if ((fcsr & (1 << cc)) == 0)
2035 target = pc + offset;
2038 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2039 if ((fcsr & (1 << cc)) != 0)
2040 target = pc + offset;
2047 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2054 bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
2055 bool success = false;
2058 int64_t target, pc, offset;
2062 * condition <- (FPR[ft].bit0 == 0)
2064 * offset = sign_ext (offset)
2065 * PC = PC + 4 + offset
2067 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2068 offset = insn.getOperand(1).getImm();
2070 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2074 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2079 if ((ft_val & 1) == 0)
2080 target = pc + 4 + offset;
2086 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2093 bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
2094 bool success = false;
2097 int64_t target, pc, offset;
2101 * condition <- (FPR[ft].bit0 != 0)
2103 * offset = sign_ext (offset)
2104 * PC = PC + 4 + offset
2106 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2107 offset = insn.getOperand(1).getImm();
2109 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2113 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2118 if ((ft_val & 1) != 0)
2119 target = pc + 4 + offset;
2125 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2133 Emulate MIPS-3D Branch instructions
2134 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2136 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2139 bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
2140 bool success = false;
2142 int64_t pc, offset, target = 0;
2143 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2145 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2146 offset = insn.getOperand(1).getImm();
2148 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2152 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64,
2157 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2158 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2160 if (!strcasecmp(op_name, "BC1ANY2F")) {
2161 /* if any one bit is 0 */
2162 if (((fcsr >> cc) & 3) != 3)
2163 target = pc + offset;
2166 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2167 /* if any one bit is 1 */
2168 if (((fcsr >> cc) & 3) != 0)
2169 target = pc + offset;
2172 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2173 /* if any one bit is 0 */
2174 if (((fcsr >> cc) & 0xf) != 0xf)
2175 target = pc + offset;
2178 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2179 /* if any one bit is 1 */
2180 if (((fcsr >> cc) & 0xf) != 0)
2181 target = pc + offset;
2188 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2195 bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
2196 return Emulate_MSA_Branch_DF(insn, 1, true);
2199 bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) {
2200 return Emulate_MSA_Branch_DF(insn, 2, true);
2203 bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) {
2204 return Emulate_MSA_Branch_DF(insn, 4, true);
2207 bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) {
2208 return Emulate_MSA_Branch_DF(insn, 8, true);
2211 bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) {
2212 return Emulate_MSA_Branch_DF(insn, 1, false);
2215 bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) {
2216 return Emulate_MSA_Branch_DF(insn, 2, false);
2219 bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) {
2220 return Emulate_MSA_Branch_DF(insn, 4, false);
2223 bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) {
2224 return Emulate_MSA_Branch_DF(insn, 8, false);
2227 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2228 int element_byte_size,
2230 bool success = false, branch_hit = true;
2232 RegisterValue reg_value;
2233 const uint8_t *ptr = NULL;
2235 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2236 int64_t offset = insn.getOperand(1).getImm();
2239 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2243 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2244 ptr = (const uint8_t *)reg_value.GetBytes();
2248 for (int i = 0; i < 16 / element_byte_size; i++) {
2249 switch (element_byte_size) {
2251 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2255 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2256 (*(const uint16_t *)ptr != 0 && !bnz))
2260 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2261 (*(const uint32_t *)ptr != 0 && !bnz))
2265 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2266 (*(const uint64_t *)ptr != 0 && !bnz))
2272 ptr = ptr + element_byte_size;
2276 target = pc + offset;
2281 context.type = eContextRelativeBranchImmediate;
2283 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2290 bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
2291 return Emulate_MSA_Branch_V(insn, true);
2294 bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) {
2295 return Emulate_MSA_Branch_V(insn, false);
2298 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2300 bool success = false;
2302 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2303 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2304 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2305 RegisterValue reg_value;
2307 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2308 int64_t offset = insn.getOperand(1).getImm();
2311 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2315 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2316 wr_val = reg_value.GetAsUInt128(fail_value);
2320 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2321 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2322 target = pc + offset;
2327 context.type = eContextRelativeBranchImmediate;
2329 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2336 bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
2337 bool success = false;
2339 int64_t imm, address;
2340 Context bad_vaddr_context;
2342 uint32_t num_operands = insn.getNumOperands();
2344 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2345 imm = insn.getOperand(num_operands - 1).getImm();
2347 RegisterInfo reg_info_base;
2348 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2352 /* read base register */
2353 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2358 /* destination address */
2359 address = address + imm;
2361 /* Set the bad_vaddr register with base address used in the instruction */
2362 bad_vaddr_context.type = eContextInvalid;
2363 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
2369 bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) {
2370 bool success = false;
2371 uint32_t base, index;
2372 int64_t address, index_address;
2373 Context bad_vaddr_context;
2375 uint32_t num_operands = insn.getNumOperands();
2377 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2379 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
2381 RegisterInfo reg_info_base, reg_info_index;
2382 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2386 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
2390 /* read base register */
2391 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2396 /* read index register */
2397 index_address = ReadRegisterUnsigned(eRegisterKindDWARF,
2398 dwarf_zero_mips + index, 0, &success);
2402 /* destination address */
2403 address = address + index_address;
2405 /* Set the bad_vaddr register with base address used in the instruction */
2406 bad_vaddr_context.type = eContextInvalid;
2407 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,