1 //===-- EmulateInstructionMIPS.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 "EmulateInstructionMIPS.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/Symbol/UnwindPlan.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/ArchSpec.h"
21 #include "lldb/Utility/ConstString.h"
22 #include "lldb/Utility/DataExtractor.h"
23 #include "lldb/Utility/Stream.h"
24 #include "llvm-c/Disassembler.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/TargetSelect.h"
35 #include "llvm/ADT/STLExtras.h"
37 #include "Plugins/Process/Utility/InstructionUtils.h"
38 #include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64
41 using namespace lldb_private;
43 #define UInt(x) ((uint64_t)x)
44 #define integer int64_t
46 //----------------------------------------------------------------------
48 // EmulateInstructionMIPS implementation
50 //----------------------------------------------------------------------
54 void LLVMInitializeMipsTargetInfo();
55 void LLVMInitializeMipsTarget();
56 void LLVMInitializeMipsAsmPrinter();
57 void LLVMInitializeMipsTargetMC();
58 void LLVMInitializeMipsDisassembler();
62 EmulateInstructionMIPS::EmulateInstructionMIPS(
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,";
149 m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
150 assert(m_reg_info.get());
152 m_insn_info.reset(target->createMCInstrInfo());
153 assert(m_insn_info.get());
155 m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
156 m_subtype_info.reset(
157 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
158 assert(m_asm_info.get() && m_subtype_info.get());
161 new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
162 assert(m_context.get());
164 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
165 assert(m_disasm.get());
167 /* Create alternate disassembler for microMIPS */
168 if (arch_flags & ArchSpec::eMIPSAse_mips16)
169 features += "+mips16,";
170 else if (arch_flags & ArchSpec::eMIPSAse_micromips)
171 features += "+micromips,";
173 m_alt_subtype_info.reset(
174 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
175 assert(m_alt_subtype_info.get());
178 target->createMCDisassembler(*m_alt_subtype_info, *m_context));
179 assert(m_alt_disasm.get());
181 m_next_inst_size = 0;
182 m_use_alt_disaasm = false;
185 void EmulateInstructionMIPS::Initialize() {
186 PluginManager::RegisterPlugin(GetPluginNameStatic(),
187 GetPluginDescriptionStatic(), CreateInstance);
190 void EmulateInstructionMIPS::Terminate() {
191 PluginManager::UnregisterPlugin(CreateInstance);
194 ConstString EmulateInstructionMIPS::GetPluginNameStatic() {
195 ConstString g_plugin_name("lldb.emulate-instruction.mips32");
196 return g_plugin_name;
199 lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() {
200 static ConstString g_plugin_name("EmulateInstructionMIPS");
201 return g_plugin_name;
204 const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() {
205 return "Emulate instructions for the MIPS32 architecture.";
209 EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
210 InstructionType inst_type) {
211 if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
213 if (arch.GetTriple().getArch() == llvm::Triple::mips ||
214 arch.GetTriple().getArch() == llvm::Triple::mipsel) {
215 return new EmulateInstructionMIPS(arch);
222 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
223 if (arch.GetTriple().getArch() == llvm::Triple::mips ||
224 arch.GetTriple().getArch() == llvm::Triple::mipsel)
229 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
230 bool alternate_name) {
231 if (alternate_name) {
369 case dwarf_mcsr_mips:
371 case dwarf_config5_mips:
380 case dwarf_zero_mips:
452 case dwarf_cause_mips:
520 case dwarf_fcsr_mips:
588 case dwarf_mcsr_mips:
592 case dwarf_config5_mips:
598 bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
600 RegisterInfo ®_info) {
601 if (reg_kind == eRegisterKindGeneric) {
603 case LLDB_REGNUM_GENERIC_PC:
604 reg_kind = eRegisterKindDWARF;
605 reg_num = dwarf_pc_mips;
607 case LLDB_REGNUM_GENERIC_SP:
608 reg_kind = eRegisterKindDWARF;
609 reg_num = dwarf_sp_mips;
611 case LLDB_REGNUM_GENERIC_FP:
612 reg_kind = eRegisterKindDWARF;
613 reg_num = dwarf_r30_mips;
615 case LLDB_REGNUM_GENERIC_RA:
616 reg_kind = eRegisterKindDWARF;
617 reg_num = dwarf_ra_mips;
619 case LLDB_REGNUM_GENERIC_FLAGS:
620 reg_kind = eRegisterKindDWARF;
621 reg_num = dwarf_sr_mips;
628 if (reg_kind == eRegisterKindDWARF) {
629 ::memset(®_info, 0, sizeof(RegisterInfo));
630 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
632 if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
633 reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
634 reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
635 reg_info.byte_size = 4;
636 reg_info.format = eFormatHex;
637 reg_info.encoding = eEncodingUint;
638 } else if ((int)reg_num >= dwarf_zero_mips &&
639 (int)reg_num <= dwarf_f31_mips) {
640 reg_info.byte_size = 4;
641 reg_info.format = eFormatHex;
642 reg_info.encoding = eEncodingUint;
643 } else if ((int)reg_num >= dwarf_w0_mips &&
644 (int)reg_num <= dwarf_w31_mips) {
645 reg_info.byte_size = 16;
646 reg_info.format = eFormatVectorOfUInt8;
647 reg_info.encoding = eEncodingVector;
652 reg_info.name = GetRegisterName(reg_num, false);
653 reg_info.alt_name = GetRegisterName(reg_num, true);
654 reg_info.kinds[eRegisterKindDWARF] = reg_num;
658 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
661 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
664 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
667 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
670 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
680 EmulateInstructionMIPS::MipsOpcode *
681 EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
682 static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
683 //----------------------------------------------------------------------
684 // Prologue/Epilogue instructions
685 //----------------------------------------------------------------------
686 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
687 "ADDIU rt, rs, immediate"},
688 {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
689 {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
690 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
691 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
692 {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
694 //----------------------------------------------------------------------
695 // MicroMIPS Prologue/Epilogue instructions
696 //----------------------------------------------------------------------
697 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
699 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
700 "ADDIUS5 rd,immediate"},
701 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
702 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
703 "SWM16 reglist,offset(sp)"},
704 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
705 "SWM32 reglist,offset(base)"},
706 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
707 "SWP rs1,offset(base)"},
708 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
709 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
710 "LWM16 reglist,offset(sp)"},
711 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
712 "LWM32 reglist,offset(base)"},
713 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
714 "LWP rd,offset(base)"},
715 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
716 "JRADDIUSP immediate"},
717 //----------------------------------------------------------------------
719 // Load/Store instructions
720 //----------------------------------------------------------------------
721 /* Following list of emulated instructions are required by implementation
722 of hardware watchpoint
723 for MIPS in lldb. As we just need the address accessed by instructions,
725 all these instructions in 2 functions depending on their addressing
728 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
729 "LB rt, offset(base)"},
730 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
731 "LBE rt, offset(base)"},
732 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
733 "LBU rt, offset(base)"},
734 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
735 "LBUE rt, offset(base)"},
736 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
737 "LDC1 ft, offset(base)"},
738 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
739 "LD rt, offset(base)"},
740 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
741 "LDL rt, offset(base)"},
742 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
743 "LDR rt, offset(base)"},
744 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
745 "LLD rt, offset(base)"},
746 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
747 "LDC2 rt, offset(base)"},
748 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
749 "LDXC1 fd, index (base)"},
750 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
751 "LH rt, offset(base)"},
752 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
753 "LHE rt, offset(base)"},
754 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
755 "LHU rt, offset(base)"},
756 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
757 "LHUE rt, offset(base)"},
758 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
759 "LL rt, offset(base)"},
760 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
761 "LLE rt, offset(base)"},
762 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
763 "LUXC1 fd, index (base)"},
764 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
765 "LW rt, offset(base)"},
766 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
767 "LWC1 ft, offset(base)"},
768 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
769 "LWC2 rt, offset(base)"},
770 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
771 "LWE rt, offset(base)"},
772 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
773 "LWL rt, offset(base)"},
774 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
775 "LWLE rt, offset(base)"},
776 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
777 "LWR rt, offset(base)"},
778 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
779 "LWRE rt, offset(base)"},
780 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
781 "LWXC1 fd, index (base)"},
782 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
783 "LLX rt, offset(base)"},
784 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
785 "LLXE rt, offset(base)"},
786 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
787 "LLDX rt, offset(base)"},
789 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
790 "SB rt, offset(base)"},
791 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
792 "SBE rt, offset(base)"},
793 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
794 "SC rt, offset(base)"},
795 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
796 "SCE rt, offset(base)"},
797 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
798 "SCD rt, offset(base)"},
799 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
800 "SD rt, offset(base)"},
801 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
802 "SDL rt, offset(base)"},
803 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
804 "SDR rt, offset(base)"},
805 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
806 "SDC1 ft, offset(base)"},
807 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
808 "SDC2 rt, offset(base)"},
809 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
810 "SDXC1 fs, index(base)"},
811 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
812 "SH rt, offset(base)"},
813 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
814 "SHE rt, offset(base)"},
815 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
816 "SUXC1 fs, index (base)"},
817 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
818 "SWC1 ft, offset(base)"},
819 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
820 "SWC2 rt, offset(base)"},
821 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
822 "SWE rt, offset(base)"},
823 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
824 "SWL rt, offset(base)"},
825 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
826 "SWLE rt, offset(base)"},
827 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
828 "SWR rt, offset(base)"},
829 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
830 "SWRE rt, offset(base)"},
831 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
832 "SWXC1 fs, index (base)"},
833 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
834 "SCX rt, offset(base)"},
835 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
836 "SCXE rt, offset(base)"},
837 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
838 "SCDX rt, offset(base)"},
840 //----------------------------------------------------------------------
841 // MicroMIPS Load/Store instructions
842 //----------------------------------------------------------------------
843 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
844 "LBU16 rt, decoded_offset(base)"},
845 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
846 "LHU16 rt, left_shifted_offset(base)"},
847 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
848 "LW16 rt, left_shifted_offset(base)"},
849 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
850 "LWGP rt, left_shifted_offset(gp)"},
851 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
852 "SH16 rt, left_shifted_offset(base)"},
853 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
854 "SW16 rt, left_shifted_offset(base)"},
855 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
856 "SWSP rt, left_shifted_offset(base)"},
857 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
858 "SB16 rt, offset(base)"},
860 //----------------------------------------------------------------------
861 // Branch instructions
862 //----------------------------------------------------------------------
863 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
864 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
865 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
866 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
867 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
868 "BGEZALL rt,offset"},
869 {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
870 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
872 {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
873 {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
874 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
875 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
876 "BLEZALC rs,offset"},
877 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
878 "BGEZALC rs,offset"},
879 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
880 "BLTZALC rs,offset"},
881 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
882 "BGTZALC rs,offset"},
883 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
884 "BEQZALC rs,offset"},
885 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
886 "BNEZALC rs,offset"},
887 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
888 "BEQC rs,rt,offset"},
889 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
890 "BNEC rs,rt,offset"},
891 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
892 "BLTC rs,rt,offset"},
893 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
894 "BGEC rs,rt,offset"},
895 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
896 "BLTUC rs,rt,offset"},
897 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
898 "BGEUC rs,rt,offset"},
899 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
900 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
901 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
902 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
903 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
904 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
905 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
906 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
907 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
908 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
909 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
910 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
911 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
913 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
914 "BLTZALL rt,offset"},
915 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
916 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
917 "BOVC rs,rt,offset"},
918 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
919 "BNVC rs,rt,offset"},
920 {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
921 {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
922 {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
923 {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
924 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
925 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
926 {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
927 {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
928 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
929 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
930 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
931 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
932 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
933 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
934 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
935 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
936 "BC1ANY2F cc, offset"},
937 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
938 "BC1ANY2T cc, offset"},
939 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
940 "BC1ANY4F cc, offset"},
941 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
942 "BC1ANY4T cc, offset"},
943 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
944 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
945 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
946 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
947 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
948 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
949 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
950 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
951 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
952 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
954 //----------------------------------------------------------------------
955 // MicroMIPS Branch instructions
956 //----------------------------------------------------------------------
957 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
958 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
959 "BEQZ16 rs, offset"},
960 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
961 "BNEZ16 rs, offset"},
962 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
964 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
966 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
967 "BGEZALS rs, offset"},
968 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
969 "BLTZALS rs, offset"},
970 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
971 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
972 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
973 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
974 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
975 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
976 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
979 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
981 for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
982 if (!strcasecmp(g_opcodes[i].op_name, op_name))
983 return &g_opcodes[i];
990 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
991 uint64_t inst_addr) {
992 uint64_t next_inst_size = 0;
993 llvm::MCInst mc_insn;
994 llvm::MCDisassembler::DecodeStatus decode_status;
995 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
997 if (m_use_alt_disaasm)
999 m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
1000 inst_addr, llvm::nulls(), llvm::nulls());
1003 m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
1004 llvm::nulls(), llvm::nulls());
1006 if (decode_status != llvm::MCDisassembler::Success)
1009 return m_insn_info->get(mc_insn.getOpcode()).getSize();
1012 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
1013 const Address &inst_addr,
1015 m_use_alt_disaasm = false;
1017 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
1018 if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) {
1020 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1023 * The address belongs to microMIPS function. To find the size of
1024 * next instruction use microMIPS disassembler.
1026 m_use_alt_disaasm = true;
1028 uint32_t current_inst_size = insn_opcode.GetByteSize();
1029 uint8_t buf[sizeof(uint32_t)];
1030 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
1031 Address next_addr(next_inst_addr);
1033 const size_t bytes_read =
1034 target->ReadMemory(next_addr, /* Address of next instruction */
1035 true, /* prefer_file_cache */
1036 buf, sizeof(uint32_t), error, &load_addr);
1038 if (bytes_read == 0)
1041 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1042 GetAddressByteSize());
1043 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1047 * If the address class is not eAddressClassCodeAlternateISA then
1048 * the function is not microMIPS. In this case instruction size is
1051 m_next_inst_size = 4;
1058 bool EmulateInstructionMIPS::ReadInstruction() {
1059 bool success = false;
1060 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1061 LLDB_INVALID_ADDRESS, &success);
1063 Context read_inst_context;
1064 read_inst_context.type = eContextReadOpcode;
1065 read_inst_context.SetNoArgs();
1066 m_opcode.SetOpcode32(
1067 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1071 m_addr = LLDB_INVALID_ADDRESS;
1075 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1076 bool success = false;
1077 llvm::MCInst mc_insn;
1081 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1083 if (m_opcode.GetData(data)) {
1084 llvm::MCDisassembler::DecodeStatus decode_status;
1085 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1086 if (m_use_alt_disaasm)
1087 decode_status = m_alt_disasm->getInstruction(
1088 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1090 decode_status = m_disasm->getInstruction(
1091 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1093 if (decode_status != llvm::MCDisassembler::Success)
1098 * mc_insn.getOpcode() returns decoded opcode. However to make use
1099 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1101 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1103 if (op_name == NULL)
1107 * Decoding has been done already. Just get the call-back function
1108 * and emulate the instruction.
1110 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1112 if (opcode_data == NULL)
1115 uint64_t old_pc = 0, new_pc = 0;
1116 const bool auto_advance_pc =
1117 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1119 if (auto_advance_pc) {
1121 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1126 /* emulate instruction */
1127 success = (this->*opcode_data->callback)(mc_insn);
1131 if (auto_advance_pc) {
1133 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1137 /* If we haven't changed the PC, change it here */
1138 if (old_pc == new_pc) {
1141 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1150 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1151 UnwindPlan &unwind_plan) {
1152 unwind_plan.Clear();
1153 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1155 UnwindPlan::RowSP row(new UnwindPlan::Row);
1156 const bool can_replace = false;
1158 // Our previous Call Frame Address is the stack pointer
1159 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1161 // Our previous PC is in the RA
1162 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1164 unwind_plan.AppendRow(row);
1166 // All other registers are the same.
1167 unwind_plan.SetSourceName("EmulateInstructionMIPS");
1168 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1169 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1170 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1175 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1177 case dwarf_r16_mips:
1178 case dwarf_r17_mips:
1179 case dwarf_r18_mips:
1180 case dwarf_r19_mips:
1181 case dwarf_r20_mips:
1182 case dwarf_r21_mips:
1183 case dwarf_r22_mips:
1184 case dwarf_r23_mips:
1187 case dwarf_r30_mips:
1196 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1197 // ADDIU rt, rs, immediate
1198 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1201 bool success = false;
1202 const uint32_t imm16 = insn.getOperand(2).getImm();
1203 int64_t imm = SignedBits(imm16, 15, 0);
1205 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1206 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1208 // If immediate value is greater then 2^16 - 1 then clang generate
1209 // LUI, ADDIU, SUBU instructions in prolog.
1212 // addiu $1, $1, -0x5920
1213 // subu $sp, $sp, $1
1214 // In this case, ADDIU dst and src will be same and not equal to sp
1218 /* read <src> register */
1219 const int64_t src_opd_val = ReadRegisterUnsigned(
1220 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1224 /* Check if this is daddiu sp, sp, imm16 */
1225 if (dst == dwarf_sp_mips) {
1226 uint64_t result = src_opd_val + imm;
1227 RegisterInfo reg_info_sp;
1229 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1230 context.SetRegisterPlusOffset(reg_info_sp, imm);
1232 /* We are allocating bytes on stack */
1233 context.type = eContextAdjustStackPointer;
1235 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1240 context.SetImmediateSigned(imm);
1241 context.type = eContextImmediate;
1243 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1244 dwarf_zero_mips + dst, imm))
1251 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1252 bool success = false;
1253 uint32_t imm16 = insn.getOperand(2).getImm();
1254 uint32_t imm = SignedBits(imm16, 15, 0);
1257 Context bad_vaddr_context;
1259 RegisterInfo reg_info_base;
1261 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1262 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1264 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1268 /* read base register */
1269 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1270 dwarf_zero_mips + base, 0, &success);
1274 /* destination address */
1275 address = address + imm;
1277 /* Set the bad_vaddr register with base address used in the instruction */
1278 bad_vaddr_context.type = eContextInvalid;
1279 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1282 /* We look for sp based non-volatile register stores */
1283 if (nonvolatile_reg_p(src)) {
1285 RegisterInfo reg_info_src;
1287 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1292 RegisterValue data_src;
1293 context.type = eContextPushRegisterOnStack;
1294 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1296 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1299 if (!ReadRegister(®_info_base, data_src))
1302 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1303 eByteOrderLittle, error) == 0)
1306 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1315 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1316 bool success = false;
1318 int32_t imm, address;
1319 Context bad_vaddr_context;
1321 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1322 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1323 imm = insn.getOperand(2).getImm();
1325 RegisterInfo reg_info_base;
1326 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1330 /* read base register */
1331 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1332 dwarf_zero_mips + base, 0, &success);
1336 /* destination address */
1337 address = address + imm;
1339 /* Set the bad_vaddr register with base address used in the instruction */
1340 bad_vaddr_context.type = eContextInvalid;
1341 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1344 if (nonvolatile_reg_p(src)) {
1345 RegisterValue data_src;
1346 RegisterInfo reg_info_src;
1348 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1353 context.type = eContextPopRegisterOffStack;
1354 context.SetAddress(address);
1356 if (!WriteRegister(context, ®_info_src, data_src))
1365 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1366 // SUBU sp, <src>, <rt>
1367 // ADDU sp, <src>, <rt>
1368 // ADDU dst, sp, <rt>
1370 bool success = false;
1372 uint8_t src, dst, rt;
1373 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1375 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1376 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1378 /* Check if sp is destination register */
1379 if (dst == dwarf_sp_mips) {
1380 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1382 /* read <src> register */
1383 uint64_t src_opd_val = ReadRegisterUnsigned(
1384 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1388 /* read <rt > register */
1389 uint64_t rt_opd_val = ReadRegisterUnsigned(
1390 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1394 if (!strcasecmp(op_name, "SUBU"))
1395 result = src_opd_val - rt_opd_val;
1397 result = src_opd_val + rt_opd_val;
1400 RegisterInfo reg_info_sp;
1401 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1402 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1404 /* We are allocating bytes on stack */
1405 context.type = eContextAdjustStackPointer;
1407 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1410 } else if (src == dwarf_sp_mips) {
1411 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1413 /* read <src> register */
1414 uint64_t src_opd_val = ReadRegisterUnsigned(
1415 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1419 /* read <rt> register */
1420 uint64_t rt_opd_val = ReadRegisterUnsigned(
1421 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1427 if (!strcasecmp(op_name, "SUBU"))
1428 result = src_opd_val - rt_opd_val;
1430 result = src_opd_val + rt_opd_val;
1432 context.SetImmediateSigned(result);
1433 context.type = eContextImmediate;
1435 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1436 dwarf_zero_mips + dst, result))
1443 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1444 // LUI rt, immediate
1445 // GPR[rt] <- sign_extend(immediate << 16)
1447 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1448 int64_t imm = SignedBits(imm32, 31, 0);
1452 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1453 context.SetImmediateSigned(imm);
1454 context.type = eContextImmediate;
1456 if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
1463 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1464 bool success = false;
1465 const uint32_t imm9 = insn.getOperand(0).getImm();
1468 // This instruction operates implicitly on stack pointer, so read <sp>
1470 uint64_t src_opd_val =
1471 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1475 result = src_opd_val + imm9;
1478 RegisterInfo reg_info_sp;
1479 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1480 context.SetRegisterPlusOffset(reg_info_sp, imm9);
1482 // We are adjusting the stack.
1483 context.type = eContextAdjustStackPointer;
1485 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1489 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1490 bool success = false;
1492 const uint32_t imm4 = insn.getOperand(2).getImm();
1495 // The source and destination register is same for this instruction.
1496 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1498 // We are looking for stack adjustment only
1499 if (base == dwarf_sp_mips) {
1500 // Read stack pointer register
1501 uint64_t src_opd_val = ReadRegisterUnsigned(
1502 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1506 result = src_opd_val + imm4;
1509 RegisterInfo reg_info_sp;
1510 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1511 context.SetRegisterPlusOffset(reg_info_sp, imm4);
1513 // We are adjusting the stack.
1514 context.type = eContextAdjustStackPointer;
1516 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1522 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1523 bool success = false;
1524 uint32_t imm5 = insn.getOperand(2).getImm();
1526 Context bad_vaddr_context;
1529 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1530 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1532 RegisterInfo reg_info_base;
1534 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1538 // read base register
1539 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1544 // destination address
1545 address = address + imm5;
1547 // We use bad_vaddr_context to store base address which is used by H/W
1549 // Set the bad_vaddr register with base address used in the instruction
1550 bad_vaddr_context.type = eContextInvalid;
1551 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1554 // We look for sp based non-volatile register stores.
1555 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1556 RegisterInfo reg_info_src = {};
1558 RegisterValue data_src;
1559 context.type = eContextPushRegisterOnStack;
1560 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1562 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1565 if (!ReadRegister(®_info_base, data_src))
1568 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1569 eByteOrderLittle, error) == 0)
1572 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1581 /* Emulate SWM16,SWM32 and SWP instruction.
1583 SWM16 always has stack pointer as a base register (but it is still available
1584 in MCInst as an operand).
1585 SWM32 and SWP can have base register other than stack pointer.
1587 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1588 bool success = false;
1590 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1591 // no of regs to store.
1593 // Base register is second last operand of the instruction.
1595 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1597 // We are looking for sp based stores so if base is not a stack pointer then
1599 if (base != dwarf_sp_mips)
1602 // offset is always the last operand.
1603 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1605 RegisterInfo reg_info_base;
1606 RegisterInfo reg_info_src;
1608 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1613 uint32_t base_address = ReadRegisterUnsigned(
1614 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1618 // Resulting base addrss
1619 base_address = base_address + offset;
1621 // Total no of registers to be stored are num_operands-2.
1622 for (uint32_t i = 0; i < num_operands - 2; i++) {
1623 // Get the register number to be stored.
1624 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1627 Record only non-volatile stores.
1628 This check is required for SWP instruction because source operand could
1630 SWM16 and SWM32 instruction always has saved registers as source
1633 if (!nonvolatile_reg_p(src))
1636 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1641 RegisterValue data_src;
1642 context.type = eContextPushRegisterOnStack;
1643 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1645 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1648 if (!ReadRegister(®_info_base, data_src))
1651 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1652 eByteOrderLittle, error) == 0)
1655 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
1658 // Stack address for next register
1659 base_address = base_address + reg_info_src.byte_size;
1664 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1665 bool success = false;
1666 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1667 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1668 uint32_t imm5 = insn.getOperand(2).getImm();
1669 Context bad_vaddr_context;
1671 RegisterInfo reg_info_base;
1672 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1676 // read base register
1677 uint32_t base_address = ReadRegisterUnsigned(
1678 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1682 base_address = base_address + imm5;
1684 // We use bad_vaddr_context to store base address which is used by H/W
1686 // Set the bad_vaddr register with base address used in the instruction
1687 bad_vaddr_context.type = eContextInvalid;
1688 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1691 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1692 RegisterValue data_src;
1693 RegisterInfo reg_info_src;
1695 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1700 context.type = eContextPopRegisterOffStack;
1701 context.SetAddress(base_address);
1703 if (!WriteRegister(context, ®_info_src, data_src))
1712 /* Emulate LWM16, LWM32 and LWP instructions.
1714 LWM16 always has stack pointer as a base register (but it is still available
1715 in MCInst as an operand).
1716 LWM32 and LWP can have base register other than stack pointer.
1718 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1719 bool success = false;
1721 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1722 // no of regs to store.
1723 uint32_t imm = insn.getOperand(num_operands - 1)
1724 .getImm(); // imm is the last operand in the instruction.
1726 // Base register is second last operand of the instruction.
1728 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1730 // We are looking for sp based loads so if base is not a stack pointer then
1732 if (base != dwarf_sp_mips)
1735 uint32_t base_address = ReadRegisterUnsigned(
1736 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1740 base_address = base_address + imm;
1742 RegisterValue data_dst;
1743 RegisterInfo reg_info_dst;
1745 // Total no of registers to be re-stored are num_operands-2.
1746 for (uint32_t i = 0; i < num_operands - 2; i++) {
1747 // Get the register number to be re-stored.
1748 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1751 Record only non-volatile loads.
1752 This check is required for LWP instruction because destination operand
1753 could be any register.
1754 LWM16 and LWM32 instruction always has saved registers as destination
1757 if (!nonvolatile_reg_p(dst))
1760 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
1765 context.type = eContextPopRegisterOffStack;
1766 context.SetAddress(base_address + (i * 4));
1768 if (!WriteRegister(context, ®_info_dst, data_dst))
1775 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1776 bool success = false;
1777 int32_t imm5 = insn.getOperand(0).getImm();
1779 /* JRADDIUSP immediate
1781 * SP <- SP + zero_extend(Immediate << 2)
1784 // This instruction operates implicitly on stack pointer, so read <sp>
1786 int32_t src_opd_val =
1787 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1792 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1796 int32_t result = src_opd_val + imm5;
1801 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1805 RegisterInfo reg_info_sp;
1806 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1807 context.SetRegisterPlusOffset(reg_info_sp, imm5);
1809 // We are adjusting stack
1810 context.type = eContextAdjustStackPointer;
1813 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1820 static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1821 int32_t r = (uint32_t)a + (uint32_t)b;
1822 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1826 Emulate below MIPS branch instructions.
1827 BEQ, BNE : Branch on condition
1828 BEQL, BNEL : Branch likely
1830 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1831 bool success = false;
1833 int32_t offset, pc, target = 0, rs_val, rt_val;
1834 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1836 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1837 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1838 offset = insn.getOperand(2).getImm();
1840 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1844 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1845 dwarf_zero_mips + rs, 0, &success);
1849 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1850 dwarf_zero_mips + rt, 0, &success);
1854 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1855 if (rs_val == rt_val)
1856 target = pc + offset;
1859 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1860 if (rs_val != rt_val)
1861 target = pc + offset;
1867 context.type = eContextRelativeBranchImmediate;
1868 context.SetImmediate(offset);
1870 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1878 Emulate below MIPS branch instructions.
1879 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1880 instructions with no delay slot
1882 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1883 bool success = false;
1885 int32_t offset, pc, target = 0, rs_val, rt_val;
1886 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1887 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1889 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1890 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1891 offset = insn.getOperand(2).getImm();
1893 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1897 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1898 dwarf_zero_mips + rs, 0, &success);
1902 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1903 dwarf_zero_mips + rt, 0, &success);
1907 if (!strcasecmp(op_name, "BEQC")) {
1908 if (rs_val == rt_val)
1909 target = pc + offset;
1912 } else if (!strcasecmp(op_name, "BNEC")) {
1913 if (rs_val != rt_val)
1914 target = pc + offset;
1917 } else if (!strcasecmp(op_name, "BLTC")) {
1918 if (rs_val < rt_val)
1919 target = pc + offset;
1922 } else if (!strcasecmp(op_name, "BGEC")) {
1923 if (rs_val >= rt_val)
1924 target = pc + offset;
1927 } else if (!strcasecmp(op_name, "BLTUC")) {
1928 if (rs_val < rt_val)
1929 target = pc + offset;
1932 } else if (!strcasecmp(op_name, "BGEUC")) {
1933 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1934 target = pc + offset;
1937 } else if (!strcasecmp(op_name, "BOVC")) {
1938 if (IsAdd64bitOverflow(rs_val, rt_val))
1939 target = pc + offset;
1942 } else if (!strcasecmp(op_name, "BNVC")) {
1943 if (!IsAdd64bitOverflow(rs_val, rt_val))
1944 target = pc + offset;
1950 context.type = eContextRelativeBranchImmediate;
1951 context.SetImmediate(current_inst_size + offset);
1953 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1961 Emulate below MIPS conditional branch and link instructions.
1962 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1964 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1965 bool success = false;
1967 int32_t offset, pc, target = 0;
1969 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1971 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1972 offset = insn.getOperand(1).getImm();
1974 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1978 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1979 dwarf_zero_mips + rs, 0, &success);
1983 if (!strcasecmp(op_name, "BLEZALC")) {
1985 target = pc + offset;
1988 } else if (!strcasecmp(op_name, "BGEZALC")) {
1990 target = pc + offset;
1993 } else if (!strcasecmp(op_name, "BLTZALC")) {
1995 target = pc + offset;
1998 } else if (!strcasecmp(op_name, "BGTZALC")) {
2000 target = pc + offset;
2003 } else if (!strcasecmp(op_name, "BEQZALC")) {
2005 target = pc + offset;
2008 } else if (!strcasecmp(op_name, "BNEZALC")) {
2010 target = pc + offset;
2017 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2021 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2029 Emulate below MIPS Non-Compact conditional branch and link instructions.
2031 BLTZALL, BGEZALL : Branch likely
2033 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
2034 bool success = false;
2036 int32_t offset, pc, target = 0;
2038 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2040 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2041 offset = insn.getOperand(1).getImm();
2043 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2047 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2048 dwarf_zero_mips + rs, 0, &success);
2052 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
2053 if ((int32_t)rs_val < 0)
2054 target = pc + offset;
2057 } else if (!strcasecmp(op_name, "BGEZAL") ||
2058 !strcasecmp(op_name, "BGEZALL")) {
2059 if ((int32_t)rs_val >= 0)
2060 target = pc + offset;
2067 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2071 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2079 Emulate below MIPS branch instructions.
2080 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2081 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2083 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2084 bool success = false;
2086 int32_t offset, pc, target = 0;
2088 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2090 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2091 offset = insn.getOperand(1).getImm();
2093 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2097 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2098 dwarf_zero_mips + rs, 0, &success);
2102 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
2104 target = pc + offset;
2107 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
2109 target = pc + offset;
2112 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
2114 target = pc + offset;
2117 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
2119 target = pc + offset;
2125 context.type = eContextRelativeBranchImmediate;
2126 context.SetImmediate(offset);
2128 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2136 Emulate below MIPS branch instructions.
2137 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2139 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2140 bool success = false;
2142 int32_t offset, pc, target = 0;
2144 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2145 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2147 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2148 offset = insn.getOperand(1).getImm();
2150 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2154 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2155 dwarf_zero_mips + rs, 0, &success);
2159 if (!strcasecmp(op_name, "BLTZC")) {
2161 target = pc + offset;
2164 } else if (!strcasecmp(op_name, "BLEZC")) {
2166 target = pc + offset;
2169 } else if (!strcasecmp(op_name, "BGEZC")) {
2171 target = pc + offset;
2174 } else if (!strcasecmp(op_name, "BGTZC")) {
2176 target = pc + offset;
2179 } else if (!strcasecmp(op_name, "BEQZC")) {
2181 target = pc + offset;
2184 } else if (!strcasecmp(op_name, "BNEZC")) {
2186 target = pc + offset;
2192 context.type = eContextRelativeBranchImmediate;
2193 context.SetImmediate(current_inst_size + offset);
2195 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2202 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2203 bool success = false;
2204 int32_t offset, pc, target;
2205 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2207 offset = insn.getOperand(0).getImm();
2209 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2213 // unconditional branch
2214 target = pc + offset;
2217 context.type = eContextRelativeBranchImmediate;
2218 context.SetImmediate(current_inst_size + offset);
2220 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2228 BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2229 BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2230 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2232 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2233 bool success = false;
2235 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2236 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2237 bool update_ra = false;
2238 uint32_t ra_offset = 0;
2242 * condition <- (GPR[rs] = 0)
2244 * PC = PC + sign_ext (offset || 0)
2247 * condition <- (GPR[rs] != 0)
2249 * PC = PC + sign_ext (offset || 0)
2251 * BEQZC rs, offset (compact instruction: No delay slot)
2252 * condition <- (GPR[rs] == 0)
2254 * PC = PC + 4 + sign_ext (offset || 0)
2257 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2258 int32_t offset = insn.getOperand(1).getImm();
2261 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2265 int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2266 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2270 if (!strcasecmp(op_name, "BEQZ16_MM")) {
2272 target = pc + offset;
2274 target = pc + current_inst_size +
2275 m_next_inst_size; // Skip delay slot instruction.
2276 } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
2278 target = pc + offset;
2280 target = pc + current_inst_size +
2281 m_next_inst_size; // Skip delay slot instruction.
2282 } else if (!strcasecmp(op_name, "BEQZC_MM")) {
2284 target = pc + 4 + offset;
2288 4; // 32 bit instruction and does not have delay slot instruction.
2289 } else if (!strcasecmp(op_name, "BNEZC_MM")) {
2291 target = pc + 4 + offset;
2295 4; // 32 bit instruction and does not have delay slot instruction.
2296 } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
2298 target = pc + offset;
2300 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2304 } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
2306 target = pc + offset;
2308 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2315 context.type = eContextRelativeBranchImmediate;
2316 context.SetImmediate(current_inst_size + offset);
2318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2323 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2330 /* Emulate micromips jump instructions.
2333 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2334 bool success = false;
2335 uint32_t ra_offset = 0;
2336 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2338 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2341 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2345 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2346 dwarf_zero_mips + rs, 0, &success);
2350 if (!strcasecmp(op_name, "JALR16_MM"))
2351 ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2352 else if (!strcasecmp(op_name, "JALRS16_MM"))
2353 ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2361 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2368 /* Emulate JALS and JALX instructions.
2369 JALS 32 bit instruction with short (2-byte) delay slot.
2370 JALX 32 bit instruction with 4-byte delay slot.
2372 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2373 bool success = false;
2374 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2375 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2380 * offset = sign_ext (offset << 1)
2381 * PC = PC[31-27] | offset
2384 * offset = sign_ext (offset << 2)
2385 * PC = PC[31-28] | offset
2387 offset = insn.getOperand(0).getImm();
2389 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2393 // These are PC-region branches and not PC-relative.
2394 if (!strcasecmp(op_name, "JALS_MM")) {
2395 // target address is in the “current” 128 MB-aligned region
2396 target = (pc & 0xF8000000UL) | offset;
2398 } else if (!strcasecmp(op_name, "JALX_MM")) {
2399 // target address is in the “current” 256 MB-aligned region
2400 target = (pc & 0xF0000000UL) | offset;
2406 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2410 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2417 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2418 bool success = false;
2419 uint32_t rs = 0, rt = 0;
2420 int32_t pc = 0, rs_val = 0;
2428 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2429 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2431 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2432 dwarf_zero_mips + rs, 0, &success);
2436 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2442 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2446 // This is 4-byte instruction with 2-byte delay slot.
2447 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2454 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2455 bool success = false;
2456 int32_t offset, pc, target;
2460 * offset = sign_ext (offset << 2)
2464 offset = insn.getOperand(0).getImm();
2466 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2470 target = pc + offset;
2474 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2478 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2485 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2486 bool success = false;
2487 int32_t offset, pc, target;
2491 * offset = sign_ext (offset << 2)
2493 * PC = PC + 4 + offset
2495 offset = insn.getOperand(0).getImm();
2497 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2501 target = pc + offset;
2505 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2509 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2516 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2517 bool success = false;
2518 int32_t offset, pc, target;
2522 * offset = sign_ext (offset << 2)
2523 * PC = PC + 4 + offset
2525 offset = insn.getOperand(0).getImm();
2527 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2531 target = pc + offset;
2535 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2542 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2543 bool success = false;
2544 uint32_t offset, pc;
2548 * offset = sign_ext (offset << 2)
2549 * PC = PC[63-28] | offset
2551 offset = insn.getOperand(0).getImm();
2553 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2557 /* This is a PC-region branch and not PC-relative */
2558 pc = (pc & 0xF0000000UL) | offset;
2562 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc))
2568 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2569 bool success = false;
2570 uint32_t offset, target, pc;
2574 * offset = sign_ext (offset << 2)
2575 * PC = PC[63-28] | offset
2577 offset = insn.getOperand(0).getImm();
2579 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2583 /* This is a PC-region branch and not PC-relative */
2584 target = (pc & 0xF0000000UL) | offset;
2588 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2592 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2599 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2600 bool success = false;
2602 uint32_t pc, rs_val;
2609 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2610 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2612 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2616 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2623 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2627 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2634 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2635 bool success = false;
2637 int32_t target, offset, pc, rt_val;
2641 * offset = sign_ext (offset)
2642 * PC = GPR[rt] + offset
2645 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2646 offset = insn.getOperand(1).getImm();
2648 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2652 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2653 dwarf_zero_mips + rt, 0, &success);
2657 target = rt_val + offset;
2661 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2665 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2672 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2673 bool success = false;
2675 int32_t target, offset, rt_val;
2679 * offset = sign_ext (offset)
2680 * PC = GPR[rt] + offset
2682 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2683 offset = insn.getOperand(1).getImm();
2685 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2686 dwarf_zero_mips + rt, 0, &success);
2690 target = rt_val + offset;
2694 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2701 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2702 bool success = false;
2710 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2712 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2719 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2727 Emulate Branch on FP True/False
2728 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2729 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2731 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2732 bool success = false;
2734 int32_t pc, offset, target = 0;
2735 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2737 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2738 offset = insn.getOperand(1).getImm();
2740 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2744 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2748 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2749 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2751 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2752 if ((fcsr & (1 << cc)) == 0)
2753 target = pc + offset;
2756 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2757 if ((fcsr & (1 << cc)) != 0)
2758 target = pc + offset;
2764 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2771 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2772 bool success = false;
2775 int32_t target, pc, offset;
2779 * condition <- (FPR[ft].bit0 == 0)
2781 * offset = sign_ext (offset)
2782 * PC = PC + 4 + offset
2784 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2785 offset = insn.getOperand(1).getImm();
2787 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2791 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2796 if ((ft_val & 1) == 0)
2797 target = pc + 4 + offset;
2803 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2810 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2811 bool success = false;
2814 int32_t target, pc, offset;
2818 * condition <- (FPR[ft].bit0 != 0)
2820 * offset = sign_ext (offset)
2821 * PC = PC + 4 + offset
2823 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2824 offset = insn.getOperand(1).getImm();
2826 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2830 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2835 if ((ft_val & 1) != 0)
2836 target = pc + 4 + offset;
2842 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2850 Emulate MIPS-3D Branch instructions
2851 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2853 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2856 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2857 bool success = false;
2859 int32_t pc, offset, target = 0;
2860 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2862 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2863 offset = insn.getOperand(1).getImm();
2865 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2869 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2874 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2875 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2877 if (!strcasecmp(op_name, "BC1ANY2F")) {
2878 /* if any one bit is 0 */
2879 if (((fcsr >> cc) & 3) != 3)
2880 target = pc + offset;
2883 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2884 /* if any one bit is 1 */
2885 if (((fcsr >> cc) & 3) != 0)
2886 target = pc + offset;
2889 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2890 /* if any one bit is 0 */
2891 if (((fcsr >> cc) & 0xf) != 0xf)
2892 target = pc + offset;
2895 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2896 /* if any one bit is 1 */
2897 if (((fcsr >> cc) & 0xf) != 0)
2898 target = pc + offset;
2904 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2911 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2912 return Emulate_MSA_Branch_DF(insn, 1, true);
2915 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2916 return Emulate_MSA_Branch_DF(insn, 2, true);
2919 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2920 return Emulate_MSA_Branch_DF(insn, 4, true);
2923 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2924 return Emulate_MSA_Branch_DF(insn, 8, true);
2927 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2928 return Emulate_MSA_Branch_DF(insn, 1, false);
2931 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2932 return Emulate_MSA_Branch_DF(insn, 2, false);
2935 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2936 return Emulate_MSA_Branch_DF(insn, 4, false);
2939 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2940 return Emulate_MSA_Branch_DF(insn, 8, false);
2943 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2944 int element_byte_size,
2946 bool success = false, branch_hit = true;
2948 RegisterValue reg_value;
2949 const uint8_t *ptr = NULL;
2951 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2952 int32_t offset = insn.getOperand(1).getImm();
2955 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2959 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2960 ptr = (const uint8_t *)reg_value.GetBytes();
2964 for (int i = 0; i < 16 / element_byte_size; i++) {
2965 switch (element_byte_size) {
2967 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2971 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2972 (*(const uint16_t *)ptr != 0 && !bnz))
2976 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2977 (*(const uint32_t *)ptr != 0 && !bnz))
2981 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2982 (*(const uint64_t *)ptr != 0 && !bnz))
2988 ptr = ptr + element_byte_size;
2992 target = pc + offset;
2997 context.type = eContextRelativeBranchImmediate;
2999 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
3006 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
3007 return Emulate_MSA_Branch_V(insn, true);
3010 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
3011 return Emulate_MSA_Branch_V(insn, false);
3014 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
3016 bool success = false;
3018 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
3019 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
3020 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
3021 RegisterValue reg_value;
3023 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
3024 int32_t offset = insn.getOperand(1).getImm();
3027 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
3031 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
3032 wr_val = reg_value.GetAsUInt128(fail_value);
3036 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
3037 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
3038 target = pc + offset;
3043 context.type = eContextRelativeBranchImmediate;
3045 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
3052 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
3053 bool success = false;
3055 int32_t imm, address;
3056 Context bad_vaddr_context;
3058 uint32_t num_operands = insn.getNumOperands();
3060 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3061 imm = insn.getOperand(num_operands - 1).getImm();
3063 RegisterInfo reg_info_base;
3064 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3068 /* read base register */
3069 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3070 dwarf_zero_mips + base, 0, &success);
3074 /* destination address */
3075 address = address + imm;
3077 /* Set the bad_vaddr register with base address used in the instruction */
3078 bad_vaddr_context.type = eContextInvalid;
3079 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3085 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3086 bool success = false;
3087 uint32_t base, index;
3088 int32_t address, index_address;
3089 Context bad_vaddr_context;
3091 uint32_t num_operands = insn.getNumOperands();
3093 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3095 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3097 RegisterInfo reg_info_base, reg_info_index;
3098 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3102 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
3106 /* read base register */
3107 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3108 dwarf_zero_mips + base, 0, &success);
3112 /* read index register */
3113 index_address = (int32_t)ReadRegisterUnsigned(
3114 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3118 /* destination address */
3119 address = address + index_address;
3121 /* Set the bad_vaddr register with base address used in the instruction */
3122 bad_vaddr_context.type = eContextInvalid;
3123 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,