1 //===-- EmulateInstructionMIPS.cpp -------------------------------*- C++-*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "EmulateInstructionMIPS.h"
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/Opcode.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Symbol/UnwindPlan.h"
17 #include "lldb/Target/Target.h"
18 #include "lldb/Utility/ArchSpec.h"
19 #include "lldb/Utility/ConstString.h"
20 #include "lldb/Utility/DataExtractor.h"
21 #include "lldb/Utility/RegisterValue.h"
22 #include "lldb/Utility/Stream.h"
23 #include "llvm-c/Disassembler.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCInstrInfo.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/TargetSelect.h"
34 #include "llvm/ADT/STLExtras.h"
36 #include "Plugins/Process/Utility/InstructionUtils.h"
37 #include "Plugins/Process/Utility/RegisterContext_mips.h"
40 using namespace lldb_private;
42 #define UInt(x) ((uint64_t)x)
43 #define integer int64_t
46 // EmulateInstructionMIPS implementation
51 void LLVMInitializeMipsTargetInfo();
52 void LLVMInitializeMipsTarget();
53 void LLVMInitializeMipsAsmPrinter();
54 void LLVMInitializeMipsTargetMC();
55 void LLVMInitializeMipsDisassembler();
59 EmulateInstructionMIPS::EmulateInstructionMIPS(
60 const lldb_private::ArchSpec &arch)
61 : EmulateInstruction(arch) {
62 /* Create instance of llvm::MCDisassembler */
64 llvm::Triple triple = arch.GetTriple();
65 const llvm::Target *target =
66 llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
69 * If we fail to get the target then we haven't registered it. The
70 * SystemInitializerCommon
71 * does not initialize targets, MCs and disassemblers. However we need the
73 * to decode the instructions so that the decoding complexity stays with LLVM.
74 * Initialize the MIPS targets and disassemblers.
78 LLVMInitializeMipsTargetInfo();
79 LLVMInitializeMipsTarget();
80 LLVMInitializeMipsAsmPrinter();
81 LLVMInitializeMipsTargetMC();
82 LLVMInitializeMipsDisassembler();
83 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
91 switch (arch.GetCore()) {
92 case ArchSpec::eCore_mips32:
93 case ArchSpec::eCore_mips32el:
96 case ArchSpec::eCore_mips32r2:
97 case ArchSpec::eCore_mips32r2el:
100 case ArchSpec::eCore_mips32r3:
101 case ArchSpec::eCore_mips32r3el:
104 case ArchSpec::eCore_mips32r5:
105 case ArchSpec::eCore_mips32r5el:
108 case ArchSpec::eCore_mips32r6:
109 case ArchSpec::eCore_mips32r6el:
112 case ArchSpec::eCore_mips64:
113 case ArchSpec::eCore_mips64el:
116 case ArchSpec::eCore_mips64r2:
117 case ArchSpec::eCore_mips64r2el:
120 case ArchSpec::eCore_mips64r3:
121 case ArchSpec::eCore_mips64r3el:
124 case ArchSpec::eCore_mips64r5:
125 case ArchSpec::eCore_mips64r5el:
128 case ArchSpec::eCore_mips64r6:
129 case ArchSpec::eCore_mips64r6el:
137 std::string features = "";
138 uint32_t arch_flags = arch.GetFlags();
139 if (arch_flags & ArchSpec::eMIPSAse_msa)
141 if (arch_flags & ArchSpec::eMIPSAse_dsp)
143 if (arch_flags & ArchSpec::eMIPSAse_dspr2)
144 features += "+dspr2,";
146 m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
147 assert(m_reg_info.get());
149 m_insn_info.reset(target->createMCInstrInfo());
150 assert(m_insn_info.get());
152 m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
153 m_subtype_info.reset(
154 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
155 assert(m_asm_info.get() && m_subtype_info.get());
158 new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
159 assert(m_context.get());
161 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
162 assert(m_disasm.get());
164 /* Create alternate disassembler for microMIPS */
165 if (arch_flags & ArchSpec::eMIPSAse_mips16)
166 features += "+mips16,";
167 else if (arch_flags & ArchSpec::eMIPSAse_micromips)
168 features += "+micromips,";
170 m_alt_subtype_info.reset(
171 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
172 assert(m_alt_subtype_info.get());
175 target->createMCDisassembler(*m_alt_subtype_info, *m_context));
176 assert(m_alt_disasm.get());
178 m_next_inst_size = 0;
179 m_use_alt_disaasm = false;
182 void EmulateInstructionMIPS::Initialize() {
183 PluginManager::RegisterPlugin(GetPluginNameStatic(),
184 GetPluginDescriptionStatic(), CreateInstance);
187 void EmulateInstructionMIPS::Terminate() {
188 PluginManager::UnregisterPlugin(CreateInstance);
191 ConstString EmulateInstructionMIPS::GetPluginNameStatic() {
192 ConstString g_plugin_name("lldb.emulate-instruction.mips32");
193 return g_plugin_name;
196 lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() {
197 static ConstString g_plugin_name("EmulateInstructionMIPS");
198 return g_plugin_name;
201 const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() {
202 return "Emulate instructions for the MIPS32 architecture.";
206 EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
207 InstructionType inst_type) {
208 if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
210 if (arch.GetTriple().getArch() == llvm::Triple::mips ||
211 arch.GetTriple().getArch() == llvm::Triple::mipsel) {
212 return new EmulateInstructionMIPS(arch);
219 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
220 return arch.GetTriple().getArch() == llvm::Triple::mips ||
221 arch.GetTriple().getArch() == llvm::Triple::mipsel;
224 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
225 bool alternate_name) {
226 if (alternate_name) {
364 case dwarf_mcsr_mips:
366 case dwarf_config5_mips:
375 case dwarf_zero_mips:
447 case dwarf_cause_mips:
515 case dwarf_fcsr_mips:
583 case dwarf_mcsr_mips:
587 case dwarf_config5_mips:
593 bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
595 RegisterInfo ®_info) {
596 if (reg_kind == eRegisterKindGeneric) {
598 case LLDB_REGNUM_GENERIC_PC:
599 reg_kind = eRegisterKindDWARF;
600 reg_num = dwarf_pc_mips;
602 case LLDB_REGNUM_GENERIC_SP:
603 reg_kind = eRegisterKindDWARF;
604 reg_num = dwarf_sp_mips;
606 case LLDB_REGNUM_GENERIC_FP:
607 reg_kind = eRegisterKindDWARF;
608 reg_num = dwarf_r30_mips;
610 case LLDB_REGNUM_GENERIC_RA:
611 reg_kind = eRegisterKindDWARF;
612 reg_num = dwarf_ra_mips;
614 case LLDB_REGNUM_GENERIC_FLAGS:
615 reg_kind = eRegisterKindDWARF;
616 reg_num = dwarf_sr_mips;
623 if (reg_kind == eRegisterKindDWARF) {
624 ::memset(®_info, 0, sizeof(RegisterInfo));
625 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
627 if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
628 reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
629 reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
630 reg_info.byte_size = 4;
631 reg_info.format = eFormatHex;
632 reg_info.encoding = eEncodingUint;
633 } else if ((int)reg_num >= dwarf_zero_mips &&
634 (int)reg_num <= dwarf_f31_mips) {
635 reg_info.byte_size = 4;
636 reg_info.format = eFormatHex;
637 reg_info.encoding = eEncodingUint;
638 } else if ((int)reg_num >= dwarf_w0_mips &&
639 (int)reg_num <= dwarf_w31_mips) {
640 reg_info.byte_size = 16;
641 reg_info.format = eFormatVectorOfUInt8;
642 reg_info.encoding = eEncodingVector;
647 reg_info.name = GetRegisterName(reg_num, false);
648 reg_info.alt_name = GetRegisterName(reg_num, true);
649 reg_info.kinds[eRegisterKindDWARF] = reg_num;
653 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
656 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
659 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
662 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
665 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
675 EmulateInstructionMIPS::MipsOpcode *
676 EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
677 static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
678 // Prologue/Epilogue instructions
679 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
680 "ADDIU rt, rs, immediate"},
681 {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
682 {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
683 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
684 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
685 {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
687 // MicroMIPS Prologue/Epilogue instructions
688 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
690 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
691 "ADDIUS5 rd,immediate"},
692 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
693 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
694 "SWM16 reglist,offset(sp)"},
695 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
696 "SWM32 reglist,offset(base)"},
697 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
698 "SWP rs1,offset(base)"},
699 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
700 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
701 "LWM16 reglist,offset(sp)"},
702 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
703 "LWM32 reglist,offset(base)"},
704 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
705 "LWP rd,offset(base)"},
706 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
707 "JRADDIUSP immediate"},
709 // Load/Store instructions
710 /* Following list of emulated instructions are required by implementation
711 of hardware watchpoint
712 for MIPS in lldb. As we just need the address accessed by instructions,
714 all these instructions in 2 functions depending on their addressing
717 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
718 "LB rt, offset(base)"},
719 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
720 "LBE rt, offset(base)"},
721 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
722 "LBU rt, offset(base)"},
723 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
724 "LBUE rt, offset(base)"},
725 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
726 "LDC1 ft, offset(base)"},
727 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
728 "LD rt, offset(base)"},
729 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
730 "LDL rt, offset(base)"},
731 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
732 "LDR rt, offset(base)"},
733 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
734 "LLD rt, offset(base)"},
735 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
736 "LDC2 rt, offset(base)"},
737 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
738 "LDXC1 fd, index (base)"},
739 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
740 "LH rt, offset(base)"},
741 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
742 "LHE rt, offset(base)"},
743 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
744 "LHU rt, offset(base)"},
745 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
746 "LHUE rt, offset(base)"},
747 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
748 "LL rt, offset(base)"},
749 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
750 "LLE rt, offset(base)"},
751 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
752 "LUXC1 fd, index (base)"},
753 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
754 "LW rt, offset(base)"},
755 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
756 "LWC1 ft, offset(base)"},
757 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
758 "LWC2 rt, offset(base)"},
759 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
760 "LWE rt, offset(base)"},
761 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
762 "LWL rt, offset(base)"},
763 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
764 "LWLE rt, offset(base)"},
765 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
766 "LWR rt, offset(base)"},
767 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
768 "LWRE rt, offset(base)"},
769 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
770 "LWXC1 fd, index (base)"},
771 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
772 "LLX rt, offset(base)"},
773 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
774 "LLXE rt, offset(base)"},
775 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
776 "LLDX rt, offset(base)"},
778 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
779 "SB rt, offset(base)"},
780 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
781 "SBE rt, offset(base)"},
782 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
783 "SC rt, offset(base)"},
784 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
785 "SCE rt, offset(base)"},
786 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
787 "SCD rt, offset(base)"},
788 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
789 "SD rt, offset(base)"},
790 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
791 "SDL rt, offset(base)"},
792 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
793 "SDR rt, offset(base)"},
794 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
795 "SDC1 ft, offset(base)"},
796 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
797 "SDC2 rt, offset(base)"},
798 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
799 "SDXC1 fs, index(base)"},
800 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
801 "SH rt, offset(base)"},
802 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
803 "SHE rt, offset(base)"},
804 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
805 "SUXC1 fs, index (base)"},
806 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
807 "SWC1 ft, offset(base)"},
808 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
809 "SWC2 rt, offset(base)"},
810 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
811 "SWE rt, offset(base)"},
812 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
813 "SWL rt, offset(base)"},
814 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
815 "SWLE rt, offset(base)"},
816 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
817 "SWR rt, offset(base)"},
818 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
819 "SWRE rt, offset(base)"},
820 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
821 "SWXC1 fs, index (base)"},
822 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
823 "SCX rt, offset(base)"},
824 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
825 "SCXE rt, offset(base)"},
826 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
827 "SCDX rt, offset(base)"},
829 // MicroMIPS Load/Store instructions
830 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
831 "LBU16 rt, decoded_offset(base)"},
832 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
833 "LHU16 rt, left_shifted_offset(base)"},
834 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
835 "LW16 rt, left_shifted_offset(base)"},
836 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
837 "LWGP rt, left_shifted_offset(gp)"},
838 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
839 "SH16 rt, left_shifted_offset(base)"},
840 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
841 "SW16 rt, left_shifted_offset(base)"},
842 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
843 "SWSP rt, left_shifted_offset(base)"},
844 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
845 "SB16 rt, offset(base)"},
847 // Branch instructions
848 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
849 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
850 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
851 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
852 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
853 "BGEZALL rt,offset"},
854 {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
855 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
857 {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
858 {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
859 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
860 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
861 "BLEZALC rs,offset"},
862 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
863 "BGEZALC rs,offset"},
864 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
865 "BLTZALC rs,offset"},
866 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
867 "BGTZALC rs,offset"},
868 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
869 "BEQZALC rs,offset"},
870 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
871 "BNEZALC rs,offset"},
872 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
873 "BEQC rs,rt,offset"},
874 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
875 "BNEC rs,rt,offset"},
876 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
877 "BLTC rs,rt,offset"},
878 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
879 "BGEC rs,rt,offset"},
880 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
881 "BLTUC rs,rt,offset"},
882 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
883 "BGEUC rs,rt,offset"},
884 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
885 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
886 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
887 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
888 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
889 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
890 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
891 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
892 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
893 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
894 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
895 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
896 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
898 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
899 "BLTZALL rt,offset"},
900 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
901 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
902 "BOVC rs,rt,offset"},
903 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
904 "BNVC rs,rt,offset"},
905 {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
906 {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
907 {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
908 {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
909 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
910 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
911 {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
912 {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
913 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
914 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
915 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
916 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
917 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
918 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
919 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
920 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
921 "BC1ANY2F cc, offset"},
922 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
923 "BC1ANY2T cc, offset"},
924 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
925 "BC1ANY4F cc, offset"},
926 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
927 "BC1ANY4T cc, offset"},
928 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
929 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
930 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
931 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
932 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
933 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
934 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
935 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
936 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
937 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
939 // MicroMIPS Branch instructions
940 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
941 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
942 "BEQZ16 rs, offset"},
943 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
944 "BNEZ16 rs, offset"},
945 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
947 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
949 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
950 "BGEZALS rs, offset"},
951 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
952 "BLTZALS rs, offset"},
953 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
954 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
955 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
956 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
957 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
958 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
959 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
962 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
964 for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
965 if (!strcasecmp(g_opcodes[i].op_name, op_name))
966 return &g_opcodes[i];
973 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
974 uint64_t inst_addr) {
975 uint64_t next_inst_size = 0;
976 llvm::MCInst mc_insn;
977 llvm::MCDisassembler::DecodeStatus decode_status;
978 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
980 if (m_use_alt_disaasm)
982 m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
983 inst_addr, llvm::nulls(), llvm::nulls());
986 m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
987 llvm::nulls(), llvm::nulls());
989 if (decode_status != llvm::MCDisassembler::Success)
992 return m_insn_info->get(mc_insn.getOpcode()).getSize();
995 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
996 const Address &inst_addr,
998 m_use_alt_disaasm = false;
1000 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
1001 if (inst_addr.GetAddressClass() == AddressClass::eCodeAlternateISA) {
1003 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1006 * The address belongs to microMIPS function. To find the size of
1007 * next instruction use microMIPS disassembler.
1009 m_use_alt_disaasm = true;
1011 uint32_t current_inst_size = insn_opcode.GetByteSize();
1012 uint8_t buf[sizeof(uint32_t)];
1013 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
1014 Address next_addr(next_inst_addr);
1016 const size_t bytes_read =
1017 target->ReadMemory(next_addr, /* Address of next instruction */
1018 true, /* prefer_file_cache */
1019 buf, sizeof(uint32_t), error, &load_addr);
1021 if (bytes_read == 0)
1024 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1025 GetAddressByteSize());
1026 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1030 * If the address class is not AddressClass::eCodeAlternateISA then
1031 * the function is not microMIPS. In this case instruction size is
1034 m_next_inst_size = 4;
1041 bool EmulateInstructionMIPS::ReadInstruction() {
1042 bool success = false;
1043 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1044 LLDB_INVALID_ADDRESS, &success);
1046 Context read_inst_context;
1047 read_inst_context.type = eContextReadOpcode;
1048 read_inst_context.SetNoArgs();
1049 m_opcode.SetOpcode32(
1050 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1054 m_addr = LLDB_INVALID_ADDRESS;
1058 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1059 bool success = false;
1060 llvm::MCInst mc_insn;
1064 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1066 if (m_opcode.GetData(data)) {
1067 llvm::MCDisassembler::DecodeStatus decode_status;
1068 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1069 if (m_use_alt_disaasm)
1070 decode_status = m_alt_disasm->getInstruction(
1071 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1073 decode_status = m_disasm->getInstruction(
1074 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1076 if (decode_status != llvm::MCDisassembler::Success)
1081 * mc_insn.getOpcode() returns decoded opcode. However to make use
1082 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1084 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1086 if (op_name == nullptr)
1090 * Decoding has been done already. Just get the call-back function
1091 * and emulate the instruction.
1093 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1095 if (opcode_data == nullptr)
1098 uint64_t old_pc = 0, new_pc = 0;
1099 const bool auto_advance_pc =
1100 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1102 if (auto_advance_pc) {
1104 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1109 /* emulate instruction */
1110 success = (this->*opcode_data->callback)(mc_insn);
1114 if (auto_advance_pc) {
1116 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1120 /* If we haven't changed the PC, change it here */
1121 if (old_pc == new_pc) {
1124 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1133 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1134 UnwindPlan &unwind_plan) {
1135 unwind_plan.Clear();
1136 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1138 UnwindPlan::RowSP row(new UnwindPlan::Row);
1139 const bool can_replace = false;
1141 // Our previous Call Frame Address is the stack pointer
1142 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1144 // Our previous PC is in the RA
1145 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1147 unwind_plan.AppendRow(row);
1149 // All other registers are the same.
1150 unwind_plan.SetSourceName("EmulateInstructionMIPS");
1151 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1152 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1153 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1158 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1160 case dwarf_r16_mips:
1161 case dwarf_r17_mips:
1162 case dwarf_r18_mips:
1163 case dwarf_r19_mips:
1164 case dwarf_r20_mips:
1165 case dwarf_r21_mips:
1166 case dwarf_r22_mips:
1167 case dwarf_r23_mips:
1170 case dwarf_r30_mips:
1179 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1180 // ADDIU rt, rs, immediate
1181 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1184 bool success = false;
1185 const uint32_t imm16 = insn.getOperand(2).getImm();
1186 int64_t imm = SignedBits(imm16, 15, 0);
1188 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1189 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1191 // If immediate value is greater then 2^16 - 1 then clang generate LUI,
1192 // ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1,
1193 // -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same
1194 // and not equal to sp
1198 /* read <src> register */
1199 const int64_t src_opd_val = ReadRegisterUnsigned(
1200 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1204 /* Check if this is daddiu sp, sp, imm16 */
1205 if (dst == dwarf_sp_mips) {
1206 uint64_t result = src_opd_val + imm;
1207 RegisterInfo reg_info_sp;
1209 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1210 context.SetRegisterPlusOffset(reg_info_sp, imm);
1212 /* We are allocating bytes on stack */
1213 context.type = eContextAdjustStackPointer;
1215 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1220 context.SetImmediateSigned(imm);
1221 context.type = eContextImmediate;
1223 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1224 dwarf_zero_mips + dst, imm))
1231 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1232 bool success = false;
1233 uint32_t imm16 = insn.getOperand(2).getImm();
1234 uint32_t imm = SignedBits(imm16, 15, 0);
1237 Context bad_vaddr_context;
1239 RegisterInfo reg_info_base;
1241 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1242 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1244 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1248 /* read base register */
1249 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1250 dwarf_zero_mips + base, 0, &success);
1254 /* destination address */
1255 address = address + imm;
1257 /* Set the bad_vaddr register with base address used in the instruction */
1258 bad_vaddr_context.type = eContextInvalid;
1259 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1262 /* We look for sp based non-volatile register stores */
1263 if (nonvolatile_reg_p(src)) {
1265 RegisterInfo reg_info_src;
1267 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1272 RegisterValue data_src;
1273 context.type = eContextPushRegisterOnStack;
1274 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1276 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1279 if (!ReadRegister(®_info_base, data_src))
1282 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1283 eByteOrderLittle, error) == 0)
1286 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1295 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1296 bool success = false;
1298 int32_t imm, address;
1299 Context bad_vaddr_context;
1301 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1302 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1303 imm = insn.getOperand(2).getImm();
1305 RegisterInfo reg_info_base;
1306 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1310 /* read base register */
1311 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1312 dwarf_zero_mips + base, 0, &success);
1316 /* destination address */
1317 address = address + imm;
1319 /* Set the bad_vaddr register with base address used in the instruction */
1320 bad_vaddr_context.type = eContextInvalid;
1321 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1324 if (nonvolatile_reg_p(src)) {
1325 RegisterValue data_src;
1326 RegisterInfo reg_info_src;
1328 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1333 context.type = eContextPopRegisterOffStack;
1334 context.SetAddress(address);
1336 return WriteRegister(context, ®_info_src, data_src);
1342 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1343 // SUBU sp, <src>, <rt>
1344 // ADDU sp, <src>, <rt>
1345 // ADDU dst, sp, <rt>
1347 bool success = false;
1349 uint8_t src, dst, rt;
1350 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1352 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1353 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1355 /* Check if sp is destination register */
1356 if (dst == dwarf_sp_mips) {
1357 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1359 /* read <src> register */
1360 uint64_t src_opd_val = ReadRegisterUnsigned(
1361 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1365 /* read <rt > register */
1366 uint64_t rt_opd_val = ReadRegisterUnsigned(
1367 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1371 if (!strcasecmp(op_name, "SUBU"))
1372 result = src_opd_val - rt_opd_val;
1374 result = src_opd_val + rt_opd_val;
1377 RegisterInfo reg_info_sp;
1378 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1379 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1381 /* We are allocating bytes on stack */
1382 context.type = eContextAdjustStackPointer;
1384 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1387 } else if (src == dwarf_sp_mips) {
1388 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1390 /* read <src> register */
1391 uint64_t src_opd_val = ReadRegisterUnsigned(
1392 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1396 /* read <rt> register */
1397 uint64_t rt_opd_val = ReadRegisterUnsigned(
1398 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1404 if (!strcasecmp(op_name, "SUBU"))
1405 result = src_opd_val - rt_opd_val;
1407 result = src_opd_val + rt_opd_val;
1409 context.SetImmediateSigned(result);
1410 context.type = eContextImmediate;
1412 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1413 dwarf_zero_mips + dst, result))
1420 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1421 // LUI rt, immediate
1422 // GPR[rt] <- sign_extend(immediate << 16)
1424 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1425 int64_t imm = SignedBits(imm32, 31, 0);
1429 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1430 context.SetImmediateSigned(imm);
1431 context.type = eContextImmediate;
1433 return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1434 dwarf_zero_mips + rt, imm);
1437 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1438 bool success = false;
1439 const uint32_t imm9 = insn.getOperand(0).getImm();
1442 // This instruction operates implicitly on stack pointer, so read <sp>
1444 uint64_t src_opd_val =
1445 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1449 result = src_opd_val + imm9;
1452 RegisterInfo reg_info_sp;
1453 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1454 context.SetRegisterPlusOffset(reg_info_sp, imm9);
1456 // We are adjusting the stack.
1457 context.type = eContextAdjustStackPointer;
1459 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1463 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1464 bool success = false;
1466 const uint32_t imm4 = insn.getOperand(2).getImm();
1469 // The source and destination register is same for this instruction.
1470 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1472 // We are looking for stack adjustment only
1473 if (base == dwarf_sp_mips) {
1474 // Read stack pointer register
1475 uint64_t src_opd_val = ReadRegisterUnsigned(
1476 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1480 result = src_opd_val + imm4;
1483 RegisterInfo reg_info_sp;
1484 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1485 context.SetRegisterPlusOffset(reg_info_sp, imm4);
1487 // We are adjusting the stack.
1488 context.type = eContextAdjustStackPointer;
1490 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1496 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1497 bool success = false;
1498 uint32_t imm5 = insn.getOperand(2).getImm();
1500 Context bad_vaddr_context;
1503 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1504 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1506 RegisterInfo reg_info_base;
1508 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1512 // read base register
1513 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1518 // destination address
1519 address = address + imm5;
1521 // We use bad_vaddr_context to store base address which is used by H/W
1522 // watchpoint Set the bad_vaddr register with base address used in the
1524 bad_vaddr_context.type = eContextInvalid;
1525 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1528 // We look for sp based non-volatile register stores.
1529 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1530 RegisterInfo reg_info_src = {};
1532 RegisterValue data_src;
1533 context.type = eContextPushRegisterOnStack;
1534 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1536 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1539 if (!ReadRegister(®_info_base, data_src))
1542 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1543 eByteOrderLittle, error) == 0)
1546 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1555 /* Emulate SWM16,SWM32 and SWP instruction.
1557 SWM16 always has stack pointer as a base register (but it is still available
1558 in MCInst as an operand).
1559 SWM32 and SWP can have base register other than stack pointer.
1561 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1562 bool success = false;
1564 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1565 // no of regs to store.
1567 // Base register is second last operand of the instruction.
1569 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1571 // We are looking for sp based stores so if base is not a stack pointer then
1573 if (base != dwarf_sp_mips)
1576 // offset is always the last operand.
1577 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1579 RegisterInfo reg_info_base;
1580 RegisterInfo reg_info_src;
1582 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1587 uint32_t base_address = ReadRegisterUnsigned(
1588 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1592 // Resulting base addrss
1593 base_address = base_address + offset;
1595 // Total no of registers to be stored are num_operands-2.
1596 for (uint32_t i = 0; i < num_operands - 2; i++) {
1597 // Get the register number to be stored.
1598 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1601 Record only non-volatile stores.
1602 This check is required for SWP instruction because source operand could
1604 SWM16 and SWM32 instruction always has saved registers as source
1607 if (!nonvolatile_reg_p(src))
1610 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1615 RegisterValue data_src;
1616 context.type = eContextPushRegisterOnStack;
1617 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1619 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1622 if (!ReadRegister(®_info_base, data_src))
1625 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1626 eByteOrderLittle, error) == 0)
1629 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
1632 // Stack address for next register
1633 base_address = base_address + reg_info_src.byte_size;
1638 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1639 bool success = false;
1640 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1641 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1642 uint32_t imm5 = insn.getOperand(2).getImm();
1643 Context bad_vaddr_context;
1645 RegisterInfo reg_info_base;
1646 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1650 // read base register
1651 uint32_t base_address = ReadRegisterUnsigned(
1652 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1656 base_address = base_address + imm5;
1658 // We use bad_vaddr_context to store base address which is used by H/W
1659 // watchpoint Set the bad_vaddr register with base address used in the
1661 bad_vaddr_context.type = eContextInvalid;
1662 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1665 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1666 RegisterValue data_src;
1667 RegisterInfo reg_info_src;
1669 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1674 context.type = eContextPopRegisterOffStack;
1675 context.SetAddress(base_address);
1677 return WriteRegister(context, ®_info_src, data_src);
1683 /* Emulate LWM16, LWM32 and LWP instructions.
1685 LWM16 always has stack pointer as a base register (but it is still available
1686 in MCInst as an operand).
1687 LWM32 and LWP can have base register other than stack pointer.
1689 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1690 bool success = false;
1692 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1693 // no of regs to store.
1694 uint32_t imm = insn.getOperand(num_operands - 1)
1695 .getImm(); // imm is the last operand in the instruction.
1697 // Base register is second last operand of the instruction.
1699 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1701 // We are looking for sp based loads so if base is not a stack pointer then
1703 if (base != dwarf_sp_mips)
1706 uint32_t base_address = ReadRegisterUnsigned(
1707 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1711 base_address = base_address + imm;
1713 RegisterValue data_dst;
1714 RegisterInfo reg_info_dst;
1716 // Total no of registers to be re-stored are num_operands-2.
1717 for (uint32_t i = 0; i < num_operands - 2; i++) {
1718 // Get the register number to be re-stored.
1719 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1722 Record only non-volatile loads.
1723 This check is required for LWP instruction because destination operand
1724 could be any register.
1725 LWM16 and LWM32 instruction always has saved registers as destination
1728 if (!nonvolatile_reg_p(dst))
1731 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
1736 context.type = eContextPopRegisterOffStack;
1737 context.SetAddress(base_address + (i * 4));
1739 if (!WriteRegister(context, ®_info_dst, data_dst))
1746 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1747 bool success = false;
1748 int32_t imm5 = insn.getOperand(0).getImm();
1750 /* JRADDIUSP immediate
1752 * SP <- SP + zero_extend(Immediate << 2)
1755 // This instruction operates implicitly on stack pointer, so read <sp>
1757 int32_t src_opd_val =
1758 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1763 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1767 int32_t result = src_opd_val + imm5;
1772 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1776 RegisterInfo reg_info_sp;
1777 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1778 context.SetRegisterPlusOffset(reg_info_sp, imm5);
1780 // We are adjusting stack
1781 context.type = eContextAdjustStackPointer;
1784 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1788 static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1789 int32_t r = (uint32_t)a + (uint32_t)b;
1790 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1794 Emulate below MIPS branch instructions.
1795 BEQ, BNE : Branch on condition
1796 BEQL, BNEL : Branch likely
1798 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1799 bool success = false;
1801 int32_t offset, pc, target = 0, rs_val, rt_val;
1802 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1804 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1805 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1806 offset = insn.getOperand(2).getImm();
1808 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1812 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1813 dwarf_zero_mips + rs, 0, &success);
1817 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1818 dwarf_zero_mips + rt, 0, &success);
1822 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1823 if (rs_val == rt_val)
1824 target = pc + offset;
1827 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1828 if (rs_val != rt_val)
1829 target = pc + offset;
1835 context.type = eContextRelativeBranchImmediate;
1836 context.SetImmediate(offset);
1838 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1843 Emulate below MIPS branch instructions.
1844 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1845 instructions with no delay slot
1847 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1848 bool success = false;
1850 int32_t offset, pc, target = 0, rs_val, rt_val;
1851 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1852 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1854 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1855 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1856 offset = insn.getOperand(2).getImm();
1858 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1862 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1863 dwarf_zero_mips + rs, 0, &success);
1867 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1868 dwarf_zero_mips + rt, 0, &success);
1872 if (!strcasecmp(op_name, "BEQC")) {
1873 if (rs_val == rt_val)
1874 target = pc + offset;
1877 } else if (!strcasecmp(op_name, "BNEC")) {
1878 if (rs_val != rt_val)
1879 target = pc + offset;
1882 } else if (!strcasecmp(op_name, "BLTC")) {
1883 if (rs_val < rt_val)
1884 target = pc + offset;
1887 } else if (!strcasecmp(op_name, "BGEC")) {
1888 if (rs_val >= rt_val)
1889 target = pc + offset;
1892 } else if (!strcasecmp(op_name, "BLTUC")) {
1893 if (rs_val < rt_val)
1894 target = pc + offset;
1897 } else if (!strcasecmp(op_name, "BGEUC")) {
1898 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1899 target = pc + offset;
1902 } else if (!strcasecmp(op_name, "BOVC")) {
1903 if (IsAdd64bitOverflow(rs_val, rt_val))
1904 target = pc + offset;
1907 } else if (!strcasecmp(op_name, "BNVC")) {
1908 if (!IsAdd64bitOverflow(rs_val, rt_val))
1909 target = pc + offset;
1915 context.type = eContextRelativeBranchImmediate;
1916 context.SetImmediate(current_inst_size + offset);
1918 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1923 Emulate below MIPS conditional branch and link instructions.
1924 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1926 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1927 bool success = false;
1929 int32_t offset, pc, target = 0;
1931 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1933 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1934 offset = insn.getOperand(1).getImm();
1936 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1940 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1941 dwarf_zero_mips + rs, 0, &success);
1945 if (!strcasecmp(op_name, "BLEZALC")) {
1947 target = pc + offset;
1950 } else if (!strcasecmp(op_name, "BGEZALC")) {
1952 target = pc + offset;
1955 } else if (!strcasecmp(op_name, "BLTZALC")) {
1957 target = pc + offset;
1960 } else if (!strcasecmp(op_name, "BGTZALC")) {
1962 target = pc + offset;
1965 } else if (!strcasecmp(op_name, "BEQZALC")) {
1967 target = pc + offset;
1970 } else if (!strcasecmp(op_name, "BNEZALC")) {
1972 target = pc + offset;
1979 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1983 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
1991 Emulate below MIPS Non-Compact conditional branch and link instructions.
1993 BLTZALL, BGEZALL : Branch likely
1995 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
1996 bool success = false;
1998 int32_t offset, pc, target = 0;
2000 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2002 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2003 offset = insn.getOperand(1).getImm();
2005 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2009 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2010 dwarf_zero_mips + rs, 0, &success);
2014 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
2015 if ((int32_t)rs_val < 0)
2016 target = pc + offset;
2019 } else if (!strcasecmp(op_name, "BGEZAL") ||
2020 !strcasecmp(op_name, "BGEZALL")) {
2021 if ((int32_t)rs_val >= 0)
2022 target = pc + offset;
2029 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2033 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2041 Emulate below MIPS branch instructions.
2042 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2043 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2045 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2046 bool success = false;
2048 int32_t offset, pc, target = 0;
2050 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2052 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2053 offset = insn.getOperand(1).getImm();
2055 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2059 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2060 dwarf_zero_mips + rs, 0, &success);
2064 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
2066 target = pc + offset;
2069 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
2071 target = pc + offset;
2074 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
2076 target = pc + offset;
2079 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
2081 target = pc + offset;
2087 context.type = eContextRelativeBranchImmediate;
2088 context.SetImmediate(offset);
2090 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2095 Emulate below MIPS branch instructions.
2096 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2098 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2099 bool success = false;
2101 int32_t offset, pc, target = 0;
2103 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2104 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2106 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2107 offset = insn.getOperand(1).getImm();
2109 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2113 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2114 dwarf_zero_mips + rs, 0, &success);
2118 if (!strcasecmp(op_name, "BLTZC")) {
2120 target = pc + offset;
2123 } else if (!strcasecmp(op_name, "BLEZC")) {
2125 target = pc + offset;
2128 } else if (!strcasecmp(op_name, "BGEZC")) {
2130 target = pc + offset;
2133 } else if (!strcasecmp(op_name, "BGTZC")) {
2135 target = pc + offset;
2138 } else if (!strcasecmp(op_name, "BEQZC")) {
2140 target = pc + offset;
2143 } else if (!strcasecmp(op_name, "BNEZC")) {
2145 target = pc + offset;
2151 context.type = eContextRelativeBranchImmediate;
2152 context.SetImmediate(current_inst_size + offset);
2154 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2158 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2159 bool success = false;
2160 int32_t offset, pc, target;
2161 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2163 offset = insn.getOperand(0).getImm();
2165 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2169 // unconditional branch
2170 target = pc + offset;
2173 context.type = eContextRelativeBranchImmediate;
2174 context.SetImmediate(current_inst_size + offset);
2176 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2181 BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2182 BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2183 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2185 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2186 bool success = false;
2188 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2189 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2190 bool update_ra = false;
2191 uint32_t ra_offset = 0;
2195 * condition <- (GPR[rs] = 0)
2197 * PC = PC + sign_ext (offset || 0)
2200 * condition <- (GPR[rs] != 0)
2202 * PC = PC + sign_ext (offset || 0)
2204 * BEQZC rs, offset (compact instruction: No delay slot)
2205 * condition <- (GPR[rs] == 0)
2207 * PC = PC + 4 + sign_ext (offset || 0)
2210 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2211 int32_t offset = insn.getOperand(1).getImm();
2214 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2218 int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2219 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2223 if (!strcasecmp(op_name, "BEQZ16_MM")) {
2225 target = pc + offset;
2227 target = pc + current_inst_size +
2228 m_next_inst_size; // Skip delay slot instruction.
2229 } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
2231 target = pc + offset;
2233 target = pc + current_inst_size +
2234 m_next_inst_size; // Skip delay slot instruction.
2235 } else if (!strcasecmp(op_name, "BEQZC_MM")) {
2237 target = pc + 4 + offset;
2241 4; // 32 bit instruction and does not have delay slot instruction.
2242 } else if (!strcasecmp(op_name, "BNEZC_MM")) {
2244 target = pc + 4 + offset;
2248 4; // 32 bit instruction and does not have delay slot instruction.
2249 } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
2251 target = pc + offset;
2253 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2257 } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
2259 target = pc + offset;
2261 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2268 context.type = eContextRelativeBranchImmediate;
2269 context.SetImmediate(current_inst_size + offset);
2271 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2276 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2283 /* Emulate micromips jump instructions.
2286 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2287 bool success = false;
2288 uint32_t ra_offset = 0;
2289 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2291 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2294 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2298 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2299 dwarf_zero_mips + rs, 0, &success);
2303 if (!strcasecmp(op_name, "JALR16_MM"))
2304 ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2305 else if (!strcasecmp(op_name, "JALRS16_MM"))
2306 ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2310 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2314 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2321 /* Emulate JALS and JALX instructions.
2322 JALS 32 bit instruction with short (2-byte) delay slot.
2323 JALX 32 bit instruction with 4-byte delay slot.
2325 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2326 bool success = false;
2327 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2328 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2333 * offset = sign_ext (offset << 1)
2334 * PC = PC[31-27] | offset
2337 * offset = sign_ext (offset << 2)
2338 * PC = PC[31-28] | offset
2340 offset = insn.getOperand(0).getImm();
2342 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2346 // These are PC-region branches and not PC-relative.
2347 if (!strcasecmp(op_name, "JALS_MM")) {
2348 // target address is in the “current” 128 MB-aligned region
2349 target = (pc & 0xF8000000UL) | offset;
2351 } else if (!strcasecmp(op_name, "JALX_MM")) {
2352 // target address is in the “current” 256 MB-aligned region
2353 target = (pc & 0xF0000000UL) | offset;
2359 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2363 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2370 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2371 bool success = false;
2372 uint32_t rs = 0, rt = 0;
2373 int32_t pc = 0, rs_val = 0;
2381 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2382 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2384 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2385 dwarf_zero_mips + rs, 0, &success);
2389 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2395 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2399 // This is 4-byte instruction with 2-byte delay slot.
2400 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2407 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2408 bool success = false;
2409 int32_t offset, pc, target;
2413 * offset = sign_ext (offset << 2)
2417 offset = insn.getOperand(0).getImm();
2419 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2423 target = pc + offset;
2427 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2431 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2438 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2439 bool success = false;
2440 int32_t offset, pc, target;
2444 * offset = sign_ext (offset << 2)
2446 * PC = PC + 4 + offset
2448 offset = insn.getOperand(0).getImm();
2450 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2454 target = pc + offset;
2458 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2462 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2469 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2470 bool success = false;
2471 int32_t offset, pc, target;
2475 * offset = sign_ext (offset << 2)
2476 * PC = PC + 4 + offset
2478 offset = insn.getOperand(0).getImm();
2480 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2484 target = pc + offset;
2488 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2492 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2493 bool success = false;
2494 uint32_t offset, pc;
2498 * offset = sign_ext (offset << 2)
2499 * PC = PC[63-28] | offset
2501 offset = insn.getOperand(0).getImm();
2503 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2507 /* This is a PC-region branch and not PC-relative */
2508 pc = (pc & 0xF0000000UL) | offset;
2512 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc);
2515 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2516 bool success = false;
2517 uint32_t offset, target, pc;
2521 * offset = sign_ext (offset << 2)
2522 * PC = PC[63-28] | offset
2524 offset = insn.getOperand(0).getImm();
2526 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2530 /* This is a PC-region branch and not PC-relative */
2531 target = (pc & 0xF0000000UL) | offset;
2535 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2539 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2546 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2547 bool success = false;
2549 uint32_t pc, rs_val;
2556 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2557 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2559 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2563 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2570 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2574 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2581 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2582 bool success = false;
2584 int32_t target, offset, pc, rt_val;
2588 * offset = sign_ext (offset)
2589 * PC = GPR[rt] + offset
2592 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2593 offset = insn.getOperand(1).getImm();
2595 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2599 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2600 dwarf_zero_mips + rt, 0, &success);
2604 target = rt_val + offset;
2608 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2612 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2619 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2620 bool success = false;
2622 int32_t target, offset, rt_val;
2626 * offset = sign_ext (offset)
2627 * PC = GPR[rt] + offset
2629 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2630 offset = insn.getOperand(1).getImm();
2632 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2633 dwarf_zero_mips + rt, 0, &success);
2637 target = rt_val + offset;
2641 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2645 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2646 bool success = false;
2654 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2656 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2663 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2668 Emulate Branch on FP True/False
2669 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2670 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2672 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2673 bool success = false;
2675 int32_t pc, offset, target = 0;
2676 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2678 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2679 offset = insn.getOperand(1).getImm();
2681 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2685 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2689 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2690 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2692 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2693 if ((fcsr & (1 << cc)) == 0)
2694 target = pc + offset;
2697 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2698 if ((fcsr & (1 << cc)) != 0)
2699 target = pc + offset;
2705 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2709 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2710 bool success = false;
2713 int32_t target, pc, offset;
2717 * condition <- (FPR[ft].bit0 == 0)
2719 * offset = sign_ext (offset)
2720 * PC = PC + 4 + offset
2722 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2723 offset = insn.getOperand(1).getImm();
2725 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2729 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2734 if ((ft_val & 1) == 0)
2735 target = pc + 4 + offset;
2741 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2745 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2746 bool success = false;
2749 int32_t target, pc, offset;
2753 * condition <- (FPR[ft].bit0 != 0)
2755 * offset = sign_ext (offset)
2756 * PC = PC + 4 + offset
2758 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2759 offset = insn.getOperand(1).getImm();
2761 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2765 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2770 if ((ft_val & 1) != 0)
2771 target = pc + 4 + offset;
2777 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2782 Emulate MIPS-3D Branch instructions
2783 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2785 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2788 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2789 bool success = false;
2791 int32_t pc, offset, target = 0;
2792 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2794 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2795 offset = insn.getOperand(1).getImm();
2797 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2801 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2806 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2807 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2809 if (!strcasecmp(op_name, "BC1ANY2F")) {
2810 /* if any one bit is 0 */
2811 if (((fcsr >> cc) & 3) != 3)
2812 target = pc + offset;
2815 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2816 /* if any one bit is 1 */
2817 if (((fcsr >> cc) & 3) != 0)
2818 target = pc + offset;
2821 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2822 /* if any one bit is 0 */
2823 if (((fcsr >> cc) & 0xf) != 0xf)
2824 target = pc + offset;
2827 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2828 /* if any one bit is 1 */
2829 if (((fcsr >> cc) & 0xf) != 0)
2830 target = pc + offset;
2836 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2840 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2841 return Emulate_MSA_Branch_DF(insn, 1, true);
2844 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2845 return Emulate_MSA_Branch_DF(insn, 2, true);
2848 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2849 return Emulate_MSA_Branch_DF(insn, 4, true);
2852 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2853 return Emulate_MSA_Branch_DF(insn, 8, true);
2856 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2857 return Emulate_MSA_Branch_DF(insn, 1, false);
2860 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2861 return Emulate_MSA_Branch_DF(insn, 2, false);
2864 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2865 return Emulate_MSA_Branch_DF(insn, 4, false);
2868 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2869 return Emulate_MSA_Branch_DF(insn, 8, false);
2872 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2873 int element_byte_size,
2875 bool success = false, branch_hit = true;
2877 RegisterValue reg_value;
2878 const uint8_t *ptr = nullptr;
2880 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2881 int32_t offset = insn.getOperand(1).getImm();
2884 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2888 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2889 ptr = (const uint8_t *)reg_value.GetBytes();
2893 for (int i = 0; i < 16 / element_byte_size; i++) {
2894 switch (element_byte_size) {
2896 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2900 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2901 (*(const uint16_t *)ptr != 0 && !bnz))
2905 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2906 (*(const uint32_t *)ptr != 0 && !bnz))
2910 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2911 (*(const uint64_t *)ptr != 0 && !bnz))
2917 ptr = ptr + element_byte_size;
2921 target = pc + offset;
2926 context.type = eContextRelativeBranchImmediate;
2928 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2932 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
2933 return Emulate_MSA_Branch_V(insn, true);
2936 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
2937 return Emulate_MSA_Branch_V(insn, false);
2940 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2942 bool success = false;
2944 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2945 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2946 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2947 RegisterValue reg_value;
2949 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2950 int32_t offset = insn.getOperand(1).getImm();
2953 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2957 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2958 wr_val = reg_value.GetAsUInt128(fail_value);
2962 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2963 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2964 target = pc + offset;
2969 context.type = eContextRelativeBranchImmediate;
2971 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2975 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
2976 bool success = false;
2978 int32_t imm, address;
2979 Context bad_vaddr_context;
2981 uint32_t num_operands = insn.getNumOperands();
2983 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2984 imm = insn.getOperand(num_operands - 1).getImm();
2986 RegisterInfo reg_info_base;
2987 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2991 /* read base register */
2992 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2993 dwarf_zero_mips + base, 0, &success);
2997 /* destination address */
2998 address = address + imm;
3000 /* Set the bad_vaddr register with base address used in the instruction */
3001 bad_vaddr_context.type = eContextInvalid;
3002 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3008 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3009 bool success = false;
3010 uint32_t base, index;
3011 int32_t address, index_address;
3012 Context bad_vaddr_context;
3014 uint32_t num_operands = insn.getNumOperands();
3016 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3018 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3020 RegisterInfo reg_info_base, reg_info_index;
3021 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3025 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
3029 /* read base register */
3030 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3031 dwarf_zero_mips + base, 0, &success);
3035 /* read index register */
3036 index_address = (int32_t)ReadRegisterUnsigned(
3037 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3041 /* destination address */
3042 address = address + index_address;
3044 /* Set the bad_vaddr register with base address used in the instruction */
3045 bad_vaddr_context.type = eContextInvalid;
3046 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,