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/Symbol/UnwindPlan.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/ConstString.h"
21 #include "lldb/Utility/DataExtractor.h"
22 #include "lldb/Utility/RegisterValue.h"
23 #include "lldb/Utility/Stream.h"
24 #include "llvm-c/Disassembler.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/TargetSelect.h"
35 #include "llvm/ADT/STLExtras.h"
37 #include "Plugins/Process/Utility/InstructionUtils.h"
38 #include "Plugins/Process/Utility/RegisterContext_mips.h"
41 using namespace lldb_private;
43 #define UInt(x) ((uint64_t)x)
44 #define integer int64_t
46 //----------------------------------------------------------------------
48 // 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 return arch.GetTriple().getArch() == llvm::Triple::mips ||
224 arch.GetTriple().getArch() == llvm::Triple::mipsel;
227 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
228 bool alternate_name) {
229 if (alternate_name) {
367 case dwarf_mcsr_mips:
369 case dwarf_config5_mips:
378 case dwarf_zero_mips:
450 case dwarf_cause_mips:
518 case dwarf_fcsr_mips:
586 case dwarf_mcsr_mips:
590 case dwarf_config5_mips:
596 bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
598 RegisterInfo ®_info) {
599 if (reg_kind == eRegisterKindGeneric) {
601 case LLDB_REGNUM_GENERIC_PC:
602 reg_kind = eRegisterKindDWARF;
603 reg_num = dwarf_pc_mips;
605 case LLDB_REGNUM_GENERIC_SP:
606 reg_kind = eRegisterKindDWARF;
607 reg_num = dwarf_sp_mips;
609 case LLDB_REGNUM_GENERIC_FP:
610 reg_kind = eRegisterKindDWARF;
611 reg_num = dwarf_r30_mips;
613 case LLDB_REGNUM_GENERIC_RA:
614 reg_kind = eRegisterKindDWARF;
615 reg_num = dwarf_ra_mips;
617 case LLDB_REGNUM_GENERIC_FLAGS:
618 reg_kind = eRegisterKindDWARF;
619 reg_num = dwarf_sr_mips;
626 if (reg_kind == eRegisterKindDWARF) {
627 ::memset(®_info, 0, sizeof(RegisterInfo));
628 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
630 if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
631 reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
632 reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
633 reg_info.byte_size = 4;
634 reg_info.format = eFormatHex;
635 reg_info.encoding = eEncodingUint;
636 } else if ((int)reg_num >= dwarf_zero_mips &&
637 (int)reg_num <= dwarf_f31_mips) {
638 reg_info.byte_size = 4;
639 reg_info.format = eFormatHex;
640 reg_info.encoding = eEncodingUint;
641 } else if ((int)reg_num >= dwarf_w0_mips &&
642 (int)reg_num <= dwarf_w31_mips) {
643 reg_info.byte_size = 16;
644 reg_info.format = eFormatVectorOfUInt8;
645 reg_info.encoding = eEncodingVector;
650 reg_info.name = GetRegisterName(reg_num, false);
651 reg_info.alt_name = GetRegisterName(reg_num, true);
652 reg_info.kinds[eRegisterKindDWARF] = reg_num;
656 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
659 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
662 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
665 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
668 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
678 EmulateInstructionMIPS::MipsOpcode *
679 EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
680 static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
681 //----------------------------------------------------------------------
682 // Prologue/Epilogue instructions
683 //----------------------------------------------------------------------
684 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
685 "ADDIU rt, rs, immediate"},
686 {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
687 {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
688 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
689 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
690 {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
692 //----------------------------------------------------------------------
693 // MicroMIPS Prologue/Epilogue instructions
694 //----------------------------------------------------------------------
695 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
697 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
698 "ADDIUS5 rd,immediate"},
699 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
700 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
701 "SWM16 reglist,offset(sp)"},
702 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
703 "SWM32 reglist,offset(base)"},
704 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
705 "SWP rs1,offset(base)"},
706 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
707 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
708 "LWM16 reglist,offset(sp)"},
709 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
710 "LWM32 reglist,offset(base)"},
711 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
712 "LWP rd,offset(base)"},
713 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
714 "JRADDIUSP immediate"},
715 //----------------------------------------------------------------------
717 // Load/Store instructions
718 //----------------------------------------------------------------------
719 /* Following list of emulated instructions are required by implementation
720 of hardware watchpoint
721 for MIPS in lldb. As we just need the address accessed by instructions,
723 all these instructions in 2 functions depending on their addressing
726 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
727 "LB rt, offset(base)"},
728 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
729 "LBE rt, offset(base)"},
730 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
731 "LBU rt, offset(base)"},
732 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
733 "LBUE rt, offset(base)"},
734 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
735 "LDC1 ft, offset(base)"},
736 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
737 "LD rt, offset(base)"},
738 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
739 "LDL rt, offset(base)"},
740 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
741 "LDR rt, offset(base)"},
742 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
743 "LLD rt, offset(base)"},
744 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
745 "LDC2 rt, offset(base)"},
746 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
747 "LDXC1 fd, index (base)"},
748 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
749 "LH rt, offset(base)"},
750 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
751 "LHE rt, offset(base)"},
752 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
753 "LHU rt, offset(base)"},
754 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
755 "LHUE rt, offset(base)"},
756 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
757 "LL rt, offset(base)"},
758 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
759 "LLE rt, offset(base)"},
760 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
761 "LUXC1 fd, index (base)"},
762 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
763 "LW rt, offset(base)"},
764 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
765 "LWC1 ft, offset(base)"},
766 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
767 "LWC2 rt, offset(base)"},
768 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
769 "LWE rt, offset(base)"},
770 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
771 "LWL rt, offset(base)"},
772 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
773 "LWLE rt, offset(base)"},
774 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
775 "LWR rt, offset(base)"},
776 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
777 "LWRE rt, offset(base)"},
778 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
779 "LWXC1 fd, index (base)"},
780 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
781 "LLX rt, offset(base)"},
782 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
783 "LLXE rt, offset(base)"},
784 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
785 "LLDX rt, offset(base)"},
787 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
788 "SB rt, offset(base)"},
789 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
790 "SBE rt, offset(base)"},
791 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
792 "SC rt, offset(base)"},
793 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
794 "SCE rt, offset(base)"},
795 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
796 "SCD rt, offset(base)"},
797 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
798 "SD rt, offset(base)"},
799 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
800 "SDL rt, offset(base)"},
801 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
802 "SDR rt, offset(base)"},
803 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
804 "SDC1 ft, offset(base)"},
805 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
806 "SDC2 rt, offset(base)"},
807 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
808 "SDXC1 fs, index(base)"},
809 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
810 "SH rt, offset(base)"},
811 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
812 "SHE rt, offset(base)"},
813 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
814 "SUXC1 fs, index (base)"},
815 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
816 "SWC1 ft, offset(base)"},
817 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
818 "SWC2 rt, offset(base)"},
819 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
820 "SWE rt, offset(base)"},
821 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
822 "SWL rt, offset(base)"},
823 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
824 "SWLE rt, offset(base)"},
825 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
826 "SWR rt, offset(base)"},
827 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
828 "SWRE rt, offset(base)"},
829 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
830 "SWXC1 fs, index (base)"},
831 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
832 "SCX rt, offset(base)"},
833 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
834 "SCXE rt, offset(base)"},
835 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
836 "SCDX rt, offset(base)"},
838 //----------------------------------------------------------------------
839 // MicroMIPS Load/Store instructions
840 //----------------------------------------------------------------------
841 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
842 "LBU16 rt, decoded_offset(base)"},
843 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
844 "LHU16 rt, left_shifted_offset(base)"},
845 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
846 "LW16 rt, left_shifted_offset(base)"},
847 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
848 "LWGP rt, left_shifted_offset(gp)"},
849 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
850 "SH16 rt, left_shifted_offset(base)"},
851 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
852 "SW16 rt, left_shifted_offset(base)"},
853 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
854 "SWSP rt, left_shifted_offset(base)"},
855 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
856 "SB16 rt, offset(base)"},
858 //----------------------------------------------------------------------
859 // Branch instructions
860 //----------------------------------------------------------------------
861 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
862 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
863 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
864 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
865 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
866 "BGEZALL rt,offset"},
867 {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
868 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
870 {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
871 {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
872 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
873 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
874 "BLEZALC rs,offset"},
875 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
876 "BGEZALC rs,offset"},
877 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
878 "BLTZALC rs,offset"},
879 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
880 "BGTZALC rs,offset"},
881 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
882 "BEQZALC rs,offset"},
883 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
884 "BNEZALC rs,offset"},
885 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
886 "BEQC rs,rt,offset"},
887 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
888 "BNEC rs,rt,offset"},
889 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
890 "BLTC rs,rt,offset"},
891 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
892 "BGEC rs,rt,offset"},
893 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
894 "BLTUC rs,rt,offset"},
895 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
896 "BGEUC rs,rt,offset"},
897 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
898 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
899 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
900 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
901 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
902 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
903 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
904 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
905 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
906 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
907 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
908 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
909 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
911 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
912 "BLTZALL rt,offset"},
913 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
914 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
915 "BOVC rs,rt,offset"},
916 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
917 "BNVC rs,rt,offset"},
918 {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
919 {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
920 {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
921 {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
922 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
923 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
924 {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
925 {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
926 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
927 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
928 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
929 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
930 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
931 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
932 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
933 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
934 "BC1ANY2F cc, offset"},
935 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
936 "BC1ANY2T cc, offset"},
937 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
938 "BC1ANY4F cc, offset"},
939 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
940 "BC1ANY4T cc, offset"},
941 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
942 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
943 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
944 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
945 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
946 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
947 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
948 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
949 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
950 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
952 //----------------------------------------------------------------------
953 // MicroMIPS Branch instructions
954 //----------------------------------------------------------------------
955 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
956 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
957 "BEQZ16 rs, offset"},
958 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
959 "BNEZ16 rs, offset"},
960 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
962 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
964 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
965 "BGEZALS rs, offset"},
966 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
967 "BLTZALS rs, offset"},
968 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
969 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
970 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
971 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
972 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
973 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
974 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
977 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
979 for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
980 if (!strcasecmp(g_opcodes[i].op_name, op_name))
981 return &g_opcodes[i];
988 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
989 uint64_t inst_addr) {
990 uint64_t next_inst_size = 0;
991 llvm::MCInst mc_insn;
992 llvm::MCDisassembler::DecodeStatus decode_status;
993 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
995 if (m_use_alt_disaasm)
997 m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
998 inst_addr, llvm::nulls(), llvm::nulls());
1001 m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
1002 llvm::nulls(), llvm::nulls());
1004 if (decode_status != llvm::MCDisassembler::Success)
1007 return m_insn_info->get(mc_insn.getOpcode()).getSize();
1010 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
1011 const Address &inst_addr,
1013 m_use_alt_disaasm = false;
1015 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
1016 if (inst_addr.GetAddressClass() == AddressClass::eCodeAlternateISA) {
1018 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1021 * The address belongs to microMIPS function. To find the size of
1022 * next instruction use microMIPS disassembler.
1024 m_use_alt_disaasm = true;
1026 uint32_t current_inst_size = insn_opcode.GetByteSize();
1027 uint8_t buf[sizeof(uint32_t)];
1028 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
1029 Address next_addr(next_inst_addr);
1031 const size_t bytes_read =
1032 target->ReadMemory(next_addr, /* Address of next instruction */
1033 true, /* prefer_file_cache */
1034 buf, sizeof(uint32_t), error, &load_addr);
1036 if (bytes_read == 0)
1039 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1040 GetAddressByteSize());
1041 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1045 * If the address class is not AddressClass::eCodeAlternateISA then
1046 * the function is not microMIPS. In this case instruction size is
1049 m_next_inst_size = 4;
1056 bool EmulateInstructionMIPS::ReadInstruction() {
1057 bool success = false;
1058 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1059 LLDB_INVALID_ADDRESS, &success);
1061 Context read_inst_context;
1062 read_inst_context.type = eContextReadOpcode;
1063 read_inst_context.SetNoArgs();
1064 m_opcode.SetOpcode32(
1065 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1069 m_addr = LLDB_INVALID_ADDRESS;
1073 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1074 bool success = false;
1075 llvm::MCInst mc_insn;
1079 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1081 if (m_opcode.GetData(data)) {
1082 llvm::MCDisassembler::DecodeStatus decode_status;
1083 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1084 if (m_use_alt_disaasm)
1085 decode_status = m_alt_disasm->getInstruction(
1086 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1088 decode_status = m_disasm->getInstruction(
1089 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1091 if (decode_status != llvm::MCDisassembler::Success)
1096 * mc_insn.getOpcode() returns decoded opcode. However to make use
1097 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1099 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1101 if (op_name == NULL)
1105 * Decoding has been done already. Just get the call-back function
1106 * and emulate the instruction.
1108 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1110 if (opcode_data == NULL)
1113 uint64_t old_pc = 0, new_pc = 0;
1114 const bool auto_advance_pc =
1115 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1117 if (auto_advance_pc) {
1119 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1124 /* emulate instruction */
1125 success = (this->*opcode_data->callback)(mc_insn);
1129 if (auto_advance_pc) {
1131 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1135 /* If we haven't changed the PC, change it here */
1136 if (old_pc == new_pc) {
1139 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1148 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1149 UnwindPlan &unwind_plan) {
1150 unwind_plan.Clear();
1151 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1153 UnwindPlan::RowSP row(new UnwindPlan::Row);
1154 const bool can_replace = false;
1156 // Our previous Call Frame Address is the stack pointer
1157 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1159 // Our previous PC is in the RA
1160 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1162 unwind_plan.AppendRow(row);
1164 // All other registers are the same.
1165 unwind_plan.SetSourceName("EmulateInstructionMIPS");
1166 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1167 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1168 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1173 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1175 case dwarf_r16_mips:
1176 case dwarf_r17_mips:
1177 case dwarf_r18_mips:
1178 case dwarf_r19_mips:
1179 case dwarf_r20_mips:
1180 case dwarf_r21_mips:
1181 case dwarf_r22_mips:
1182 case dwarf_r23_mips:
1185 case dwarf_r30_mips:
1194 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1195 // ADDIU rt, rs, immediate
1196 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1199 bool success = false;
1200 const uint32_t imm16 = insn.getOperand(2).getImm();
1201 int64_t imm = SignedBits(imm16, 15, 0);
1203 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1204 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1206 // If immediate value is greater then 2^16 - 1 then clang generate LUI,
1207 // ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1,
1208 // -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same
1209 // and not equal to sp
1213 /* read <src> register */
1214 const int64_t src_opd_val = ReadRegisterUnsigned(
1215 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1219 /* Check if this is daddiu sp, sp, imm16 */
1220 if (dst == dwarf_sp_mips) {
1221 uint64_t result = src_opd_val + imm;
1222 RegisterInfo reg_info_sp;
1224 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1225 context.SetRegisterPlusOffset(reg_info_sp, imm);
1227 /* We are allocating bytes on stack */
1228 context.type = eContextAdjustStackPointer;
1230 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1235 context.SetImmediateSigned(imm);
1236 context.type = eContextImmediate;
1238 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1239 dwarf_zero_mips + dst, imm))
1246 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1247 bool success = false;
1248 uint32_t imm16 = insn.getOperand(2).getImm();
1249 uint32_t imm = SignedBits(imm16, 15, 0);
1252 Context bad_vaddr_context;
1254 RegisterInfo reg_info_base;
1256 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1257 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1259 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1263 /* read base register */
1264 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1265 dwarf_zero_mips + base, 0, &success);
1269 /* destination address */
1270 address = address + imm;
1272 /* Set the bad_vaddr register with base address used in the instruction */
1273 bad_vaddr_context.type = eContextInvalid;
1274 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1277 /* We look for sp based non-volatile register stores */
1278 if (nonvolatile_reg_p(src)) {
1280 RegisterInfo reg_info_src;
1282 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1287 RegisterValue data_src;
1288 context.type = eContextPushRegisterOnStack;
1289 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1291 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1294 if (!ReadRegister(®_info_base, data_src))
1297 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1298 eByteOrderLittle, error) == 0)
1301 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1310 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1311 bool success = false;
1313 int32_t imm, address;
1314 Context bad_vaddr_context;
1316 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1317 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1318 imm = insn.getOperand(2).getImm();
1320 RegisterInfo reg_info_base;
1321 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1325 /* read base register */
1326 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1327 dwarf_zero_mips + base, 0, &success);
1331 /* destination address */
1332 address = address + imm;
1334 /* Set the bad_vaddr register with base address used in the instruction */
1335 bad_vaddr_context.type = eContextInvalid;
1336 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1339 if (nonvolatile_reg_p(src)) {
1340 RegisterValue data_src;
1341 RegisterInfo reg_info_src;
1343 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1348 context.type = eContextPopRegisterOffStack;
1349 context.SetAddress(address);
1351 return WriteRegister(context, ®_info_src, data_src);
1357 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1358 // SUBU sp, <src>, <rt>
1359 // ADDU sp, <src>, <rt>
1360 // ADDU dst, sp, <rt>
1362 bool success = false;
1364 uint8_t src, dst, rt;
1365 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1367 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1368 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1370 /* Check if sp is destination register */
1371 if (dst == dwarf_sp_mips) {
1372 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1374 /* read <src> register */
1375 uint64_t src_opd_val = ReadRegisterUnsigned(
1376 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1380 /* read <rt > register */
1381 uint64_t rt_opd_val = ReadRegisterUnsigned(
1382 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1386 if (!strcasecmp(op_name, "SUBU"))
1387 result = src_opd_val - rt_opd_val;
1389 result = src_opd_val + rt_opd_val;
1392 RegisterInfo reg_info_sp;
1393 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1394 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1396 /* We are allocating bytes on stack */
1397 context.type = eContextAdjustStackPointer;
1399 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1402 } else if (src == dwarf_sp_mips) {
1403 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1405 /* read <src> register */
1406 uint64_t src_opd_val = ReadRegisterUnsigned(
1407 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1411 /* read <rt> register */
1412 uint64_t rt_opd_val = ReadRegisterUnsigned(
1413 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1419 if (!strcasecmp(op_name, "SUBU"))
1420 result = src_opd_val - rt_opd_val;
1422 result = src_opd_val + rt_opd_val;
1424 context.SetImmediateSigned(result);
1425 context.type = eContextImmediate;
1427 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1428 dwarf_zero_mips + dst, result))
1435 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1436 // LUI rt, immediate
1437 // GPR[rt] <- sign_extend(immediate << 16)
1439 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1440 int64_t imm = SignedBits(imm32, 31, 0);
1444 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1445 context.SetImmediateSigned(imm);
1446 context.type = eContextImmediate;
1448 return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1449 dwarf_zero_mips + rt, imm);
1452 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1453 bool success = false;
1454 const uint32_t imm9 = insn.getOperand(0).getImm();
1457 // This instruction operates implicitly on stack pointer, so read <sp>
1459 uint64_t src_opd_val =
1460 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1464 result = src_opd_val + imm9;
1467 RegisterInfo reg_info_sp;
1468 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1469 context.SetRegisterPlusOffset(reg_info_sp, imm9);
1471 // We are adjusting the stack.
1472 context.type = eContextAdjustStackPointer;
1474 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1478 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1479 bool success = false;
1481 const uint32_t imm4 = insn.getOperand(2).getImm();
1484 // The source and destination register is same for this instruction.
1485 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1487 // We are looking for stack adjustment only
1488 if (base == dwarf_sp_mips) {
1489 // Read stack pointer register
1490 uint64_t src_opd_val = ReadRegisterUnsigned(
1491 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1495 result = src_opd_val + imm4;
1498 RegisterInfo reg_info_sp;
1499 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1500 context.SetRegisterPlusOffset(reg_info_sp, imm4);
1502 // We are adjusting the stack.
1503 context.type = eContextAdjustStackPointer;
1505 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1511 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1512 bool success = false;
1513 uint32_t imm5 = insn.getOperand(2).getImm();
1515 Context bad_vaddr_context;
1518 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1519 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1521 RegisterInfo reg_info_base;
1523 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1527 // read base register
1528 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1533 // destination address
1534 address = address + imm5;
1536 // We use bad_vaddr_context to store base address which is used by H/W
1537 // watchpoint Set the bad_vaddr register with base address used in the
1539 bad_vaddr_context.type = eContextInvalid;
1540 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1543 // We look for sp based non-volatile register stores.
1544 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1545 RegisterInfo reg_info_src = {};
1547 RegisterValue data_src;
1548 context.type = eContextPushRegisterOnStack;
1549 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1551 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1554 if (!ReadRegister(®_info_base, data_src))
1557 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1558 eByteOrderLittle, error) == 0)
1561 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1570 /* Emulate SWM16,SWM32 and SWP instruction.
1572 SWM16 always has stack pointer as a base register (but it is still available
1573 in MCInst as an operand).
1574 SWM32 and SWP can have base register other than stack pointer.
1576 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1577 bool success = false;
1579 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1580 // no of regs to store.
1582 // Base register is second last operand of the instruction.
1584 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1586 // We are looking for sp based stores so if base is not a stack pointer then
1588 if (base != dwarf_sp_mips)
1591 // offset is always the last operand.
1592 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1594 RegisterInfo reg_info_base;
1595 RegisterInfo reg_info_src;
1597 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1602 uint32_t base_address = ReadRegisterUnsigned(
1603 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1607 // Resulting base addrss
1608 base_address = base_address + offset;
1610 // Total no of registers to be stored are num_operands-2.
1611 for (uint32_t i = 0; i < num_operands - 2; i++) {
1612 // Get the register number to be stored.
1613 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1616 Record only non-volatile stores.
1617 This check is required for SWP instruction because source operand could
1619 SWM16 and SWM32 instruction always has saved registers as source
1622 if (!nonvolatile_reg_p(src))
1625 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1630 RegisterValue data_src;
1631 context.type = eContextPushRegisterOnStack;
1632 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1634 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1637 if (!ReadRegister(®_info_base, data_src))
1640 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1641 eByteOrderLittle, error) == 0)
1644 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
1647 // Stack address for next register
1648 base_address = base_address + reg_info_src.byte_size;
1653 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1654 bool success = false;
1655 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1656 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1657 uint32_t imm5 = insn.getOperand(2).getImm();
1658 Context bad_vaddr_context;
1660 RegisterInfo reg_info_base;
1661 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1665 // read base register
1666 uint32_t base_address = ReadRegisterUnsigned(
1667 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1671 base_address = base_address + imm5;
1673 // We use bad_vaddr_context to store base address which is used by H/W
1674 // watchpoint Set the bad_vaddr register with base address used in the
1676 bad_vaddr_context.type = eContextInvalid;
1677 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1680 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1681 RegisterValue data_src;
1682 RegisterInfo reg_info_src;
1684 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1689 context.type = eContextPopRegisterOffStack;
1690 context.SetAddress(base_address);
1692 return WriteRegister(context, ®_info_src, data_src);
1698 /* Emulate LWM16, LWM32 and LWP instructions.
1700 LWM16 always has stack pointer as a base register (but it is still available
1701 in MCInst as an operand).
1702 LWM32 and LWP can have base register other than stack pointer.
1704 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1705 bool success = false;
1707 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1708 // no of regs to store.
1709 uint32_t imm = insn.getOperand(num_operands - 1)
1710 .getImm(); // imm is the last operand in the instruction.
1712 // Base register is second last operand of the instruction.
1714 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1716 // We are looking for sp based loads so if base is not a stack pointer then
1718 if (base != dwarf_sp_mips)
1721 uint32_t base_address = ReadRegisterUnsigned(
1722 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1726 base_address = base_address + imm;
1728 RegisterValue data_dst;
1729 RegisterInfo reg_info_dst;
1731 // Total no of registers to be re-stored are num_operands-2.
1732 for (uint32_t i = 0; i < num_operands - 2; i++) {
1733 // Get the register number to be re-stored.
1734 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1737 Record only non-volatile loads.
1738 This check is required for LWP instruction because destination operand
1739 could be any register.
1740 LWM16 and LWM32 instruction always has saved registers as destination
1743 if (!nonvolatile_reg_p(dst))
1746 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
1751 context.type = eContextPopRegisterOffStack;
1752 context.SetAddress(base_address + (i * 4));
1754 if (!WriteRegister(context, ®_info_dst, data_dst))
1761 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1762 bool success = false;
1763 int32_t imm5 = insn.getOperand(0).getImm();
1765 /* JRADDIUSP immediate
1767 * SP <- SP + zero_extend(Immediate << 2)
1770 // This instruction operates implicitly on stack pointer, so read <sp>
1772 int32_t src_opd_val =
1773 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1778 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1782 int32_t result = src_opd_val + imm5;
1787 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1791 RegisterInfo reg_info_sp;
1792 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1793 context.SetRegisterPlusOffset(reg_info_sp, imm5);
1795 // We are adjusting stack
1796 context.type = eContextAdjustStackPointer;
1799 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1803 static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1804 int32_t r = (uint32_t)a + (uint32_t)b;
1805 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1809 Emulate below MIPS branch instructions.
1810 BEQ, BNE : Branch on condition
1811 BEQL, BNEL : Branch likely
1813 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1814 bool success = false;
1816 int32_t offset, pc, target = 0, rs_val, rt_val;
1817 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1819 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1820 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1821 offset = insn.getOperand(2).getImm();
1823 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1827 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1828 dwarf_zero_mips + rs, 0, &success);
1832 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1833 dwarf_zero_mips + rt, 0, &success);
1837 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1838 if (rs_val == rt_val)
1839 target = pc + offset;
1842 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1843 if (rs_val != rt_val)
1844 target = pc + offset;
1850 context.type = eContextRelativeBranchImmediate;
1851 context.SetImmediate(offset);
1853 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1858 Emulate below MIPS branch instructions.
1859 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1860 instructions with no delay slot
1862 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1863 bool success = false;
1865 int32_t offset, pc, target = 0, rs_val, rt_val;
1866 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1867 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1869 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1870 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1871 offset = insn.getOperand(2).getImm();
1873 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1877 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1878 dwarf_zero_mips + rs, 0, &success);
1882 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1883 dwarf_zero_mips + rt, 0, &success);
1887 if (!strcasecmp(op_name, "BEQC")) {
1888 if (rs_val == rt_val)
1889 target = pc + offset;
1892 } else if (!strcasecmp(op_name, "BNEC")) {
1893 if (rs_val != rt_val)
1894 target = pc + offset;
1897 } else if (!strcasecmp(op_name, "BLTC")) {
1898 if (rs_val < rt_val)
1899 target = pc + offset;
1902 } else if (!strcasecmp(op_name, "BGEC")) {
1903 if (rs_val >= rt_val)
1904 target = pc + offset;
1907 } else if (!strcasecmp(op_name, "BLTUC")) {
1908 if (rs_val < rt_val)
1909 target = pc + offset;
1912 } else if (!strcasecmp(op_name, "BGEUC")) {
1913 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1914 target = pc + offset;
1917 } else if (!strcasecmp(op_name, "BOVC")) {
1918 if (IsAdd64bitOverflow(rs_val, rt_val))
1919 target = pc + offset;
1922 } else if (!strcasecmp(op_name, "BNVC")) {
1923 if (!IsAdd64bitOverflow(rs_val, rt_val))
1924 target = pc + offset;
1930 context.type = eContextRelativeBranchImmediate;
1931 context.SetImmediate(current_inst_size + offset);
1933 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1938 Emulate below MIPS conditional branch and link instructions.
1939 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1941 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1942 bool success = false;
1944 int32_t offset, pc, target = 0;
1946 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1948 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1949 offset = insn.getOperand(1).getImm();
1951 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1955 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1956 dwarf_zero_mips + rs, 0, &success);
1960 if (!strcasecmp(op_name, "BLEZALC")) {
1962 target = pc + offset;
1965 } else if (!strcasecmp(op_name, "BGEZALC")) {
1967 target = pc + offset;
1970 } else if (!strcasecmp(op_name, "BLTZALC")) {
1972 target = pc + offset;
1975 } else if (!strcasecmp(op_name, "BGTZALC")) {
1977 target = pc + offset;
1980 } else if (!strcasecmp(op_name, "BEQZALC")) {
1982 target = pc + offset;
1985 } else if (!strcasecmp(op_name, "BNEZALC")) {
1987 target = pc + offset;
1994 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1998 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2006 Emulate below MIPS Non-Compact conditional branch and link instructions.
2008 BLTZALL, BGEZALL : Branch likely
2010 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
2011 bool success = false;
2013 int32_t offset, pc, target = 0;
2015 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2017 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2018 offset = insn.getOperand(1).getImm();
2020 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2024 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2025 dwarf_zero_mips + rs, 0, &success);
2029 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
2030 if ((int32_t)rs_val < 0)
2031 target = pc + offset;
2034 } else if (!strcasecmp(op_name, "BGEZAL") ||
2035 !strcasecmp(op_name, "BGEZALL")) {
2036 if ((int32_t)rs_val >= 0)
2037 target = pc + offset;
2044 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2048 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2056 Emulate below MIPS branch instructions.
2057 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2058 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2060 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2061 bool success = false;
2063 int32_t offset, pc, target = 0;
2065 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2067 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2068 offset = insn.getOperand(1).getImm();
2070 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2074 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2075 dwarf_zero_mips + rs, 0, &success);
2079 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
2081 target = pc + offset;
2084 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
2086 target = pc + offset;
2089 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
2091 target = pc + offset;
2094 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
2096 target = pc + offset;
2102 context.type = eContextRelativeBranchImmediate;
2103 context.SetImmediate(offset);
2105 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2110 Emulate below MIPS branch instructions.
2111 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2113 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2114 bool success = false;
2116 int32_t offset, pc, target = 0;
2118 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2119 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2121 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2122 offset = insn.getOperand(1).getImm();
2124 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2128 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2129 dwarf_zero_mips + rs, 0, &success);
2133 if (!strcasecmp(op_name, "BLTZC")) {
2135 target = pc + offset;
2138 } else if (!strcasecmp(op_name, "BLEZC")) {
2140 target = pc + offset;
2143 } else if (!strcasecmp(op_name, "BGEZC")) {
2145 target = pc + offset;
2148 } else if (!strcasecmp(op_name, "BGTZC")) {
2150 target = pc + offset;
2153 } else if (!strcasecmp(op_name, "BEQZC")) {
2155 target = pc + offset;
2158 } else if (!strcasecmp(op_name, "BNEZC")) {
2160 target = pc + offset;
2166 context.type = eContextRelativeBranchImmediate;
2167 context.SetImmediate(current_inst_size + offset);
2169 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2173 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2174 bool success = false;
2175 int32_t offset, pc, target;
2176 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2178 offset = insn.getOperand(0).getImm();
2180 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2184 // unconditional branch
2185 target = pc + offset;
2188 context.type = eContextRelativeBranchImmediate;
2189 context.SetImmediate(current_inst_size + offset);
2191 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2196 BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2197 BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2198 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2200 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2201 bool success = false;
2203 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2204 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2205 bool update_ra = false;
2206 uint32_t ra_offset = 0;
2210 * condition <- (GPR[rs] = 0)
2212 * PC = PC + sign_ext (offset || 0)
2215 * condition <- (GPR[rs] != 0)
2217 * PC = PC + sign_ext (offset || 0)
2219 * BEQZC rs, offset (compact instruction: No delay slot)
2220 * condition <- (GPR[rs] == 0)
2222 * PC = PC + 4 + sign_ext (offset || 0)
2225 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2226 int32_t offset = insn.getOperand(1).getImm();
2229 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2233 int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2234 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2238 if (!strcasecmp(op_name, "BEQZ16_MM")) {
2240 target = pc + offset;
2242 target = pc + current_inst_size +
2243 m_next_inst_size; // Skip delay slot instruction.
2244 } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
2246 target = pc + offset;
2248 target = pc + current_inst_size +
2249 m_next_inst_size; // Skip delay slot instruction.
2250 } else if (!strcasecmp(op_name, "BEQZC_MM")) {
2252 target = pc + 4 + offset;
2256 4; // 32 bit instruction and does not have delay slot instruction.
2257 } else if (!strcasecmp(op_name, "BNEZC_MM")) {
2259 target = pc + 4 + offset;
2263 4; // 32 bit instruction and does not have delay slot instruction.
2264 } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
2266 target = pc + offset;
2268 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2272 } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
2274 target = pc + offset;
2276 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2283 context.type = eContextRelativeBranchImmediate;
2284 context.SetImmediate(current_inst_size + offset);
2286 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2291 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2298 /* Emulate micromips jump instructions.
2301 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2302 bool success = false;
2303 uint32_t ra_offset = 0;
2304 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2306 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2309 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2313 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2314 dwarf_zero_mips + rs, 0, &success);
2318 if (!strcasecmp(op_name, "JALR16_MM"))
2319 ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2320 else if (!strcasecmp(op_name, "JALRS16_MM"))
2321 ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2325 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2329 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2336 /* Emulate JALS and JALX instructions.
2337 JALS 32 bit instruction with short (2-byte) delay slot.
2338 JALX 32 bit instruction with 4-byte delay slot.
2340 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2341 bool success = false;
2342 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2343 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2348 * offset = sign_ext (offset << 1)
2349 * PC = PC[31-27] | offset
2352 * offset = sign_ext (offset << 2)
2353 * PC = PC[31-28] | offset
2355 offset = insn.getOperand(0).getImm();
2357 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2361 // These are PC-region branches and not PC-relative.
2362 if (!strcasecmp(op_name, "JALS_MM")) {
2363 // target address is in the “current” 128 MB-aligned region
2364 target = (pc & 0xF8000000UL) | offset;
2366 } else if (!strcasecmp(op_name, "JALX_MM")) {
2367 // target address is in the “current” 256 MB-aligned region
2368 target = (pc & 0xF0000000UL) | offset;
2374 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2378 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2385 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2386 bool success = false;
2387 uint32_t rs = 0, rt = 0;
2388 int32_t pc = 0, rs_val = 0;
2396 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2397 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2399 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2400 dwarf_zero_mips + rs, 0, &success);
2404 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2410 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2414 // This is 4-byte instruction with 2-byte delay slot.
2415 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2422 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2423 bool success = false;
2424 int32_t offset, pc, target;
2428 * offset = sign_ext (offset << 2)
2432 offset = insn.getOperand(0).getImm();
2434 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2438 target = pc + offset;
2442 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2446 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2453 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2454 bool success = false;
2455 int32_t offset, pc, target;
2459 * offset = sign_ext (offset << 2)
2461 * PC = PC + 4 + offset
2463 offset = insn.getOperand(0).getImm();
2465 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2469 target = pc + offset;
2473 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2477 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2484 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2485 bool success = false;
2486 int32_t offset, pc, target;
2490 * offset = sign_ext (offset << 2)
2491 * PC = PC + 4 + offset
2493 offset = insn.getOperand(0).getImm();
2495 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2499 target = pc + offset;
2503 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2507 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2508 bool success = false;
2509 uint32_t offset, pc;
2513 * offset = sign_ext (offset << 2)
2514 * PC = PC[63-28] | offset
2516 offset = insn.getOperand(0).getImm();
2518 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2522 /* This is a PC-region branch and not PC-relative */
2523 pc = (pc & 0xF0000000UL) | offset;
2527 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc);
2530 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2531 bool success = false;
2532 uint32_t offset, target, pc;
2536 * offset = sign_ext (offset << 2)
2537 * PC = PC[63-28] | offset
2539 offset = insn.getOperand(0).getImm();
2541 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2545 /* This is a PC-region branch and not PC-relative */
2546 target = (pc & 0xF0000000UL) | offset;
2550 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2554 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2561 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2562 bool success = false;
2564 uint32_t pc, rs_val;
2571 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2572 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2574 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2578 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2585 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2589 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2596 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2597 bool success = false;
2599 int32_t target, offset, pc, rt_val;
2603 * offset = sign_ext (offset)
2604 * PC = GPR[rt] + offset
2607 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2608 offset = insn.getOperand(1).getImm();
2610 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2614 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2615 dwarf_zero_mips + rt, 0, &success);
2619 target = rt_val + offset;
2623 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2627 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2634 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2635 bool success = false;
2637 int32_t target, offset, rt_val;
2641 * offset = sign_ext (offset)
2642 * PC = GPR[rt] + offset
2644 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2645 offset = insn.getOperand(1).getImm();
2647 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2648 dwarf_zero_mips + rt, 0, &success);
2652 target = rt_val + offset;
2656 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2660 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2661 bool success = false;
2669 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2671 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2678 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2683 Emulate Branch on FP True/False
2684 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2685 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2687 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2688 bool success = false;
2690 int32_t pc, offset, target = 0;
2691 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2693 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2694 offset = insn.getOperand(1).getImm();
2696 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2700 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2704 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2705 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2707 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2708 if ((fcsr & (1 << cc)) == 0)
2709 target = pc + offset;
2712 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2713 if ((fcsr & (1 << cc)) != 0)
2714 target = pc + offset;
2720 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2724 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2725 bool success = false;
2728 int32_t target, pc, offset;
2732 * condition <- (FPR[ft].bit0 == 0)
2734 * offset = sign_ext (offset)
2735 * PC = PC + 4 + offset
2737 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2738 offset = insn.getOperand(1).getImm();
2740 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2744 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2749 if ((ft_val & 1) == 0)
2750 target = pc + 4 + offset;
2756 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2760 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2761 bool success = false;
2764 int32_t target, pc, offset;
2768 * condition <- (FPR[ft].bit0 != 0)
2770 * offset = sign_ext (offset)
2771 * PC = PC + 4 + offset
2773 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2774 offset = insn.getOperand(1).getImm();
2776 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2780 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2785 if ((ft_val & 1) != 0)
2786 target = pc + 4 + offset;
2792 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2797 Emulate MIPS-3D Branch instructions
2798 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2800 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2803 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2804 bool success = false;
2806 int32_t pc, offset, target = 0;
2807 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2809 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2810 offset = insn.getOperand(1).getImm();
2812 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2816 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2821 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2822 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2824 if (!strcasecmp(op_name, "BC1ANY2F")) {
2825 /* if any one bit is 0 */
2826 if (((fcsr >> cc) & 3) != 3)
2827 target = pc + offset;
2830 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2831 /* if any one bit is 1 */
2832 if (((fcsr >> cc) & 3) != 0)
2833 target = pc + offset;
2836 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2837 /* if any one bit is 0 */
2838 if (((fcsr >> cc) & 0xf) != 0xf)
2839 target = pc + offset;
2842 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2843 /* if any one bit is 1 */
2844 if (((fcsr >> cc) & 0xf) != 0)
2845 target = pc + offset;
2851 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2855 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2856 return Emulate_MSA_Branch_DF(insn, 1, true);
2859 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2860 return Emulate_MSA_Branch_DF(insn, 2, true);
2863 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2864 return Emulate_MSA_Branch_DF(insn, 4, true);
2867 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2868 return Emulate_MSA_Branch_DF(insn, 8, true);
2871 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2872 return Emulate_MSA_Branch_DF(insn, 1, false);
2875 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2876 return Emulate_MSA_Branch_DF(insn, 2, false);
2879 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2880 return Emulate_MSA_Branch_DF(insn, 4, false);
2883 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2884 return Emulate_MSA_Branch_DF(insn, 8, false);
2887 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2888 int element_byte_size,
2890 bool success = false, branch_hit = true;
2892 RegisterValue reg_value;
2893 const uint8_t *ptr = NULL;
2895 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2896 int32_t offset = insn.getOperand(1).getImm();
2899 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2903 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2904 ptr = (const uint8_t *)reg_value.GetBytes();
2908 for (int i = 0; i < 16 / element_byte_size; i++) {
2909 switch (element_byte_size) {
2911 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2915 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2916 (*(const uint16_t *)ptr != 0 && !bnz))
2920 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2921 (*(const uint32_t *)ptr != 0 && !bnz))
2925 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2926 (*(const uint64_t *)ptr != 0 && !bnz))
2932 ptr = ptr + element_byte_size;
2936 target = pc + offset;
2941 context.type = eContextRelativeBranchImmediate;
2943 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2947 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
2948 return Emulate_MSA_Branch_V(insn, true);
2951 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
2952 return Emulate_MSA_Branch_V(insn, false);
2955 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2957 bool success = false;
2959 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2960 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2961 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2962 RegisterValue reg_value;
2964 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2965 int32_t offset = insn.getOperand(1).getImm();
2968 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2972 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2973 wr_val = reg_value.GetAsUInt128(fail_value);
2977 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2978 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2979 target = pc + offset;
2984 context.type = eContextRelativeBranchImmediate;
2986 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2990 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
2991 bool success = false;
2993 int32_t imm, address;
2994 Context bad_vaddr_context;
2996 uint32_t num_operands = insn.getNumOperands();
2998 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2999 imm = insn.getOperand(num_operands - 1).getImm();
3001 RegisterInfo reg_info_base;
3002 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3006 /* read base register */
3007 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3008 dwarf_zero_mips + base, 0, &success);
3012 /* destination address */
3013 address = address + imm;
3015 /* Set the bad_vaddr register with base address used in the instruction */
3016 bad_vaddr_context.type = eContextInvalid;
3017 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3023 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3024 bool success = false;
3025 uint32_t base, index;
3026 int32_t address, index_address;
3027 Context bad_vaddr_context;
3029 uint32_t num_operands = insn.getNumOperands();
3031 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3033 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3035 RegisterInfo reg_info_base, reg_info_index;
3036 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3040 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
3044 /* read base register */
3045 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3046 dwarf_zero_mips + base, 0, &success);
3050 /* read index register */
3051 index_address = (int32_t)ReadRegisterUnsigned(
3052 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3056 /* destination address */
3057 address = address + index_address;
3059 /* Set the bad_vaddr register with base address used in the instruction */
3060 bad_vaddr_context.type = eContextInvalid;
3061 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,