1 //===-- EmulateInstructionMIPS.cpp -------------------------------*- C++
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #include "EmulateInstructionMIPS.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ArchSpec.h"
17 #include "lldb/Core/ConstString.h"
18 #include "lldb/Core/DataExtractor.h"
19 #include "lldb/Core/Opcode.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/Stream.h"
22 #include "lldb/Symbol/UnwindPlan.h"
23 #include "lldb/Target/Target.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(), Error);
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(), Error);
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 std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap(
216 new EmulateInstructionMIPS(arch));
217 if (emulate_insn_ap.get())
218 return emulate_insn_ap.release();
225 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
226 if (arch.GetTriple().getArch() == llvm::Triple::mips ||
227 arch.GetTriple().getArch() == llvm::Triple::mipsel)
232 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
233 bool alternate_name) {
234 if (alternate_name) {
372 case dwarf_mcsr_mips:
374 case dwarf_config5_mips:
383 case dwarf_zero_mips:
455 case dwarf_cause_mips:
523 case dwarf_fcsr_mips:
591 case dwarf_mcsr_mips:
595 case dwarf_config5_mips:
601 bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
603 RegisterInfo ®_info) {
604 if (reg_kind == eRegisterKindGeneric) {
606 case LLDB_REGNUM_GENERIC_PC:
607 reg_kind = eRegisterKindDWARF;
608 reg_num = dwarf_pc_mips;
610 case LLDB_REGNUM_GENERIC_SP:
611 reg_kind = eRegisterKindDWARF;
612 reg_num = dwarf_sp_mips;
614 case LLDB_REGNUM_GENERIC_FP:
615 reg_kind = eRegisterKindDWARF;
616 reg_num = dwarf_r30_mips;
618 case LLDB_REGNUM_GENERIC_RA:
619 reg_kind = eRegisterKindDWARF;
620 reg_num = dwarf_ra_mips;
622 case LLDB_REGNUM_GENERIC_FLAGS:
623 reg_kind = eRegisterKindDWARF;
624 reg_num = dwarf_sr_mips;
631 if (reg_kind == eRegisterKindDWARF) {
632 ::memset(®_info, 0, sizeof(RegisterInfo));
633 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
635 if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
636 reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
637 reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
638 reg_info.byte_size = 4;
639 reg_info.format = eFormatHex;
640 reg_info.encoding = eEncodingUint;
641 } else if ((int)reg_num >= dwarf_zero_mips &&
642 (int)reg_num <= dwarf_f31_mips) {
643 reg_info.byte_size = 4;
644 reg_info.format = eFormatHex;
645 reg_info.encoding = eEncodingUint;
646 } else if ((int)reg_num >= dwarf_w0_mips &&
647 (int)reg_num <= dwarf_w31_mips) {
648 reg_info.byte_size = 16;
649 reg_info.format = eFormatVectorOfUInt8;
650 reg_info.encoding = eEncodingVector;
655 reg_info.name = GetRegisterName(reg_num, false);
656 reg_info.alt_name = GetRegisterName(reg_num, true);
657 reg_info.kinds[eRegisterKindDWARF] = reg_num;
661 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
664 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
667 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
670 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
673 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
683 EmulateInstructionMIPS::MipsOpcode *
684 EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
685 static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
686 //----------------------------------------------------------------------
687 // Prologue/Epilogue instructions
688 //----------------------------------------------------------------------
689 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
690 "ADDIU rt, rs, immediate"},
691 {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
692 {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
693 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
694 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
695 {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
697 //----------------------------------------------------------------------
698 // MicroMIPS Prologue/Epilogue instructions
699 //----------------------------------------------------------------------
700 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
702 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
703 "ADDIUS5 rd,immediate"},
704 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
705 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
706 "SWM16 reglist,offset(sp)"},
707 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
708 "SWM32 reglist,offset(base)"},
709 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
710 "SWP rs1,offset(base)"},
711 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
712 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
713 "LWM16 reglist,offset(sp)"},
714 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
715 "LWM32 reglist,offset(base)"},
716 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
717 "LWP rd,offset(base)"},
718 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
719 "JRADDIUSP immediate"},
720 //----------------------------------------------------------------------
722 // Load/Store instructions
723 //----------------------------------------------------------------------
724 /* Following list of emulated instructions are required by implementation
725 of hardware watchpoint
726 for MIPS in lldb. As we just need the address accessed by instructions,
728 all these instructions in 2 functions depending on their addressing
731 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
732 "LB rt, offset(base)"},
733 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
734 "LBE rt, offset(base)"},
735 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
736 "LBU rt, offset(base)"},
737 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
738 "LBUE rt, offset(base)"},
739 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
740 "LDC1 ft, offset(base)"},
741 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
742 "LD rt, offset(base)"},
743 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
744 "LDL rt, offset(base)"},
745 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
746 "LDR rt, offset(base)"},
747 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
748 "LLD rt, offset(base)"},
749 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
750 "LDC2 rt, offset(base)"},
751 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
752 "LDXC1 fd, index (base)"},
753 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
754 "LH rt, offset(base)"},
755 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
756 "LHE rt, offset(base)"},
757 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
758 "LHU rt, offset(base)"},
759 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
760 "LHUE rt, offset(base)"},
761 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
762 "LL rt, offset(base)"},
763 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
764 "LLE rt, offset(base)"},
765 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
766 "LUXC1 fd, index (base)"},
767 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
768 "LW rt, offset(base)"},
769 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
770 "LWC1 ft, offset(base)"},
771 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
772 "LWC2 rt, offset(base)"},
773 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
774 "LWE rt, offset(base)"},
775 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
776 "LWL rt, offset(base)"},
777 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
778 "LWLE rt, offset(base)"},
779 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
780 "LWR rt, offset(base)"},
781 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
782 "LWRE rt, offset(base)"},
783 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
784 "LWXC1 fd, index (base)"},
785 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
786 "LLX rt, offset(base)"},
787 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
788 "LLXE rt, offset(base)"},
789 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
790 "LLDX rt, offset(base)"},
792 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
793 "SB rt, offset(base)"},
794 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
795 "SBE rt, offset(base)"},
796 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
797 "SC rt, offset(base)"},
798 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
799 "SCE rt, offset(base)"},
800 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
801 "SCD rt, offset(base)"},
802 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
803 "SD rt, offset(base)"},
804 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
805 "SDL rt, offset(base)"},
806 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
807 "SDR rt, offset(base)"},
808 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
809 "SDC1 ft, offset(base)"},
810 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
811 "SDC2 rt, offset(base)"},
812 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
813 "SDXC1 fs, index(base)"},
814 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
815 "SH rt, offset(base)"},
816 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
817 "SHE rt, offset(base)"},
818 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
819 "SUXC1 fs, index (base)"},
820 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
821 "SWC1 ft, offset(base)"},
822 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
823 "SWC2 rt, offset(base)"},
824 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
825 "SWE rt, offset(base)"},
826 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
827 "SWL rt, offset(base)"},
828 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
829 "SWLE rt, offset(base)"},
830 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
831 "SWR rt, offset(base)"},
832 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
833 "SWRE rt, offset(base)"},
834 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
835 "SWXC1 fs, index (base)"},
836 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
837 "SCX rt, offset(base)"},
838 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
839 "SCXE rt, offset(base)"},
840 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
841 "SCDX rt, offset(base)"},
843 //----------------------------------------------------------------------
844 // MicroMIPS Load/Store instructions
845 //----------------------------------------------------------------------
846 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
847 "LBU16 rt, decoded_offset(base)"},
848 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
849 "LHU16 rt, left_shifted_offset(base)"},
850 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
851 "LW16 rt, left_shifted_offset(base)"},
852 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
853 "LWGP rt, left_shifted_offset(gp)"},
854 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
855 "SH16 rt, left_shifted_offset(base)"},
856 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
857 "SW16 rt, left_shifted_offset(base)"},
858 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
859 "SWSP rt, left_shifted_offset(base)"},
860 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
861 "SB16 rt, offset(base)"},
863 //----------------------------------------------------------------------
864 // Branch instructions
865 //----------------------------------------------------------------------
866 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
867 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
868 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
869 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
870 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
871 "BGEZALL rt,offset"},
872 {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
873 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
875 {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
876 {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
877 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
878 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
879 "BLEZALC rs,offset"},
880 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
881 "BGEZALC rs,offset"},
882 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
883 "BLTZALC rs,offset"},
884 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
885 "BGTZALC rs,offset"},
886 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
887 "BEQZALC rs,offset"},
888 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
889 "BNEZALC rs,offset"},
890 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
891 "BEQC rs,rt,offset"},
892 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
893 "BNEC rs,rt,offset"},
894 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
895 "BLTC rs,rt,offset"},
896 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
897 "BGEC rs,rt,offset"},
898 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
899 "BLTUC rs,rt,offset"},
900 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
901 "BGEUC rs,rt,offset"},
902 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
903 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
904 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
905 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
906 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
907 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
908 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
909 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
910 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
911 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
912 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
913 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
914 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
916 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
917 "BLTZALL rt,offset"},
918 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
919 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
920 "BOVC rs,rt,offset"},
921 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
922 "BNVC rs,rt,offset"},
923 {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
924 {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
925 {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
926 {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
927 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
928 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
929 {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
930 {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
931 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
932 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
933 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
934 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
935 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
936 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
937 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
938 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
939 "BC1ANY2F cc, offset"},
940 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
941 "BC1ANY2T cc, offset"},
942 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
943 "BC1ANY4F cc, offset"},
944 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
945 "BC1ANY4T cc, offset"},
946 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
947 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
948 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
949 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
950 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
951 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
952 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
953 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
954 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
955 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
957 //----------------------------------------------------------------------
958 // MicroMIPS Branch instructions
959 //----------------------------------------------------------------------
960 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
961 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
962 "BEQZ16 rs, offset"},
963 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
964 "BNEZ16 rs, offset"},
965 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
967 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
969 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
970 "BGEZALS rs, offset"},
971 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
972 "BLTZALS rs, offset"},
973 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
974 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
975 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
976 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
977 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
978 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
979 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
982 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
984 for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
985 if (!strcasecmp(g_opcodes[i].op_name, op_name))
986 return &g_opcodes[i];
993 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
994 uint64_t inst_addr) {
995 uint64_t next_inst_size = 0;
996 llvm::MCInst mc_insn;
997 llvm::MCDisassembler::DecodeStatus decode_status;
998 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1000 if (m_use_alt_disaasm)
1002 m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
1003 inst_addr, llvm::nulls(), llvm::nulls());
1006 m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
1007 llvm::nulls(), llvm::nulls());
1009 if (decode_status != llvm::MCDisassembler::Success)
1012 return m_insn_info->get(mc_insn.getOpcode()).getSize();
1015 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
1016 const Address &inst_addr,
1018 m_use_alt_disaasm = false;
1020 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
1021 if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) {
1023 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1026 * The address belongs to microMIPS function. To find the size of
1027 * next instruction use microMIPS disassembler.
1029 m_use_alt_disaasm = true;
1031 uint32_t current_inst_size = insn_opcode.GetByteSize();
1032 uint8_t buf[sizeof(uint32_t)];
1033 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
1034 Address next_addr(next_inst_addr);
1036 const size_t bytes_read =
1037 target->ReadMemory(next_addr, /* Address of next instruction */
1038 true, /* prefer_file_cache */
1039 buf, sizeof(uint32_t), error, &load_addr);
1041 if (bytes_read == 0)
1044 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1045 GetAddressByteSize());
1046 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1050 * If the address class is not eAddressClassCodeAlternateISA then
1051 * the function is not microMIPS. In this case instruction size is
1054 m_next_inst_size = 4;
1061 bool EmulateInstructionMIPS::ReadInstruction() {
1062 bool success = false;
1063 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1064 LLDB_INVALID_ADDRESS, &success);
1066 Context read_inst_context;
1067 read_inst_context.type = eContextReadOpcode;
1068 read_inst_context.SetNoArgs();
1069 m_opcode.SetOpcode32(
1070 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1074 m_addr = LLDB_INVALID_ADDRESS;
1078 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1079 bool success = false;
1080 llvm::MCInst mc_insn;
1084 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1086 if (m_opcode.GetData(data)) {
1087 llvm::MCDisassembler::DecodeStatus decode_status;
1088 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1089 if (m_use_alt_disaasm)
1090 decode_status = m_alt_disasm->getInstruction(
1091 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1093 decode_status = m_disasm->getInstruction(
1094 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1096 if (decode_status != llvm::MCDisassembler::Success)
1101 * mc_insn.getOpcode() returns decoded opcode. However to make use
1102 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1104 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1106 if (op_name == NULL)
1110 * Decoding has been done already. Just get the call-back function
1111 * and emulate the instruction.
1113 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1115 if (opcode_data == NULL)
1118 uint64_t old_pc = 0, new_pc = 0;
1119 const bool auto_advance_pc =
1120 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1122 if (auto_advance_pc) {
1124 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1129 /* emulate instruction */
1130 success = (this->*opcode_data->callback)(mc_insn);
1134 if (auto_advance_pc) {
1136 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1140 /* If we haven't changed the PC, change it here */
1141 if (old_pc == new_pc) {
1144 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1153 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1154 UnwindPlan &unwind_plan) {
1155 unwind_plan.Clear();
1156 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1158 UnwindPlan::RowSP row(new UnwindPlan::Row);
1159 const bool can_replace = false;
1161 // Our previous Call Frame Address is the stack pointer
1162 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1164 // Our previous PC is in the RA
1165 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1167 unwind_plan.AppendRow(row);
1169 // All other registers are the same.
1170 unwind_plan.SetSourceName("EmulateInstructionMIPS");
1171 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1172 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1173 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1178 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1180 case dwarf_r16_mips:
1181 case dwarf_r17_mips:
1182 case dwarf_r18_mips:
1183 case dwarf_r19_mips:
1184 case dwarf_r20_mips:
1185 case dwarf_r21_mips:
1186 case dwarf_r22_mips:
1187 case dwarf_r23_mips:
1190 case dwarf_r30_mips:
1199 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1200 // ADDIU rt, rs, immediate
1201 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1204 bool success = false;
1205 const uint32_t imm16 = insn.getOperand(2).getImm();
1206 int64_t imm = SignedBits(imm16, 15, 0);
1208 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1209 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1211 // If immediate value is greater then 2^16 - 1 then clang generate
1212 // LUI, ADDIU, SUBU instructions in prolog.
1215 // addiu $1, $1, -0x5920
1216 // subu $sp, $sp, $1
1217 // In this case, ADDIU dst and src will be same and not equal to sp
1221 /* read <src> register */
1222 const int64_t src_opd_val = ReadRegisterUnsigned(
1223 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1227 /* Check if this is daddiu sp, sp, imm16 */
1228 if (dst == dwarf_sp_mips) {
1229 uint64_t result = src_opd_val + imm;
1230 RegisterInfo reg_info_sp;
1232 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1233 context.SetRegisterPlusOffset(reg_info_sp, imm);
1235 /* We are allocating bytes on stack */
1236 context.type = eContextAdjustStackPointer;
1238 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1243 context.SetImmediateSigned(imm);
1244 context.type = eContextImmediate;
1246 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1247 dwarf_zero_mips + dst, imm))
1254 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1255 bool success = false;
1256 uint32_t imm16 = insn.getOperand(2).getImm();
1257 uint32_t imm = SignedBits(imm16, 15, 0);
1260 Context bad_vaddr_context;
1262 RegisterInfo reg_info_base;
1264 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1265 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1267 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1271 /* read base register */
1272 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1273 dwarf_zero_mips + base, 0, &success);
1277 /* destination address */
1278 address = address + imm;
1280 /* Set the bad_vaddr register with base address used in the instruction */
1281 bad_vaddr_context.type = eContextInvalid;
1282 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1285 /* We look for sp based non-volatile register stores */
1286 if (nonvolatile_reg_p(src)) {
1288 RegisterInfo reg_info_src;
1290 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1295 RegisterValue data_src;
1296 context.type = eContextPushRegisterOnStack;
1297 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1299 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1302 if (!ReadRegister(®_info_base, data_src))
1305 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1306 eByteOrderLittle, error) == 0)
1309 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1318 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1319 bool success = false;
1321 int32_t imm, address;
1322 Context bad_vaddr_context;
1324 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1325 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1326 imm = insn.getOperand(2).getImm();
1328 RegisterInfo reg_info_base;
1329 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1333 /* read base register */
1334 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1335 dwarf_zero_mips + base, 0, &success);
1339 /* destination address */
1340 address = address + imm;
1342 /* Set the bad_vaddr register with base address used in the instruction */
1343 bad_vaddr_context.type = eContextInvalid;
1344 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1347 if (nonvolatile_reg_p(src)) {
1348 RegisterValue data_src;
1349 RegisterInfo reg_info_src;
1351 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1356 context.type = eContextPopRegisterOffStack;
1357 context.SetAddress(address);
1359 if (!WriteRegister(context, ®_info_src, data_src))
1368 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1369 // SUBU sp, <src>, <rt>
1370 // ADDU sp, <src>, <rt>
1371 // ADDU dst, sp, <rt>
1373 bool success = false;
1375 uint8_t src, dst, rt;
1376 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1378 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1379 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1381 /* Check if sp is destination register */
1382 if (dst == dwarf_sp_mips) {
1383 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1385 /* read <src> register */
1386 uint64_t src_opd_val = ReadRegisterUnsigned(
1387 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1391 /* read <rt > register */
1392 uint64_t rt_opd_val = ReadRegisterUnsigned(
1393 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1397 if (!strcasecmp(op_name, "SUBU"))
1398 result = src_opd_val - rt_opd_val;
1400 result = src_opd_val + rt_opd_val;
1403 RegisterInfo reg_info_sp;
1404 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1405 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1407 /* We are allocating bytes on stack */
1408 context.type = eContextAdjustStackPointer;
1410 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1413 } else if (src == dwarf_sp_mips) {
1414 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1416 /* read <src> register */
1417 uint64_t src_opd_val = ReadRegisterUnsigned(
1418 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1422 /* read <rt> register */
1423 uint64_t rt_opd_val = ReadRegisterUnsigned(
1424 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1430 if (!strcasecmp(op_name, "SUBU"))
1431 result = src_opd_val - rt_opd_val;
1433 result = src_opd_val + rt_opd_val;
1435 context.SetImmediateSigned(result);
1436 context.type = eContextImmediate;
1438 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1439 dwarf_zero_mips + dst, result))
1446 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1447 // LUI rt, immediate
1448 // GPR[rt] <- sign_extend(immediate << 16)
1450 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1451 int64_t imm = SignedBits(imm32, 31, 0);
1455 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1456 context.SetImmediateSigned(imm);
1457 context.type = eContextImmediate;
1459 if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
1466 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1467 bool success = false;
1468 const uint32_t imm9 = insn.getOperand(0).getImm();
1471 // This instruction operates implicitly on stack pointer, so read <sp>
1473 uint64_t src_opd_val =
1474 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1478 result = src_opd_val + imm9;
1481 RegisterInfo reg_info_sp;
1482 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1483 context.SetRegisterPlusOffset(reg_info_sp, imm9);
1485 // We are adjusting the stack.
1486 context.type = eContextAdjustStackPointer;
1488 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1492 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1493 bool success = false;
1495 const uint32_t imm4 = insn.getOperand(2).getImm();
1498 // The source and destination register is same for this instruction.
1499 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1501 // We are looking for stack adjustment only
1502 if (base == dwarf_sp_mips) {
1503 // Read stack pointer register
1504 uint64_t src_opd_val = ReadRegisterUnsigned(
1505 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1509 result = src_opd_val + imm4;
1512 RegisterInfo reg_info_sp;
1513 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1514 context.SetRegisterPlusOffset(reg_info_sp, imm4);
1516 // We are adjusting the stack.
1517 context.type = eContextAdjustStackPointer;
1519 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1525 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1526 bool success = false;
1527 uint32_t imm5 = insn.getOperand(2).getImm();
1529 Context bad_vaddr_context;
1532 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1533 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1535 RegisterInfo reg_info_base;
1537 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1541 // read base register
1542 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1547 // destination address
1548 address = address + imm5;
1550 // We use bad_vaddr_context to store base address which is used by H/W
1552 // Set the bad_vaddr register with base address used in the instruction
1553 bad_vaddr_context.type = eContextInvalid;
1554 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1557 // We look for sp based non-volatile register stores.
1558 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1559 RegisterInfo reg_info_src = {};
1561 RegisterValue data_src;
1562 context.type = eContextPushRegisterOnStack;
1563 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1565 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1568 if (!ReadRegister(®_info_base, data_src))
1571 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1572 eByteOrderLittle, error) == 0)
1575 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1584 /* Emulate SWM16,SWM32 and SWP instruction.
1586 SWM16 always has stack pointer as a base register (but it is still available
1587 in MCInst as an operand).
1588 SWM32 and SWP can have base register other than stack pointer.
1590 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1591 bool success = false;
1593 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1594 // no of regs to store.
1596 // Base register is second last operand of the instruction.
1598 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1600 // We are looking for sp based stores so if base is not a stack pointer then
1602 if (base != dwarf_sp_mips)
1605 // offset is always the last operand.
1606 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1608 RegisterInfo reg_info_base;
1609 RegisterInfo reg_info_src;
1611 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1616 uint32_t base_address = ReadRegisterUnsigned(
1617 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1621 // Resulting base addrss
1622 base_address = base_address + offset;
1624 // Total no of registers to be stored are num_operands-2.
1625 for (uint32_t i = 0; i < num_operands - 2; i++) {
1626 // Get the register number to be stored.
1627 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1630 Record only non-volatile stores.
1631 This check is required for SWP instruction because source operand could
1633 SWM16 and SWM32 instruction always has saved registers as source
1636 if (!nonvolatile_reg_p(src))
1639 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1644 RegisterValue data_src;
1645 context.type = eContextPushRegisterOnStack;
1646 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1648 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1651 if (!ReadRegister(®_info_base, data_src))
1654 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1655 eByteOrderLittle, error) == 0)
1658 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
1661 // Stack address for next register
1662 base_address = base_address + reg_info_src.byte_size;
1667 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1668 bool success = false;
1669 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1670 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1671 uint32_t imm5 = insn.getOperand(2).getImm();
1672 Context bad_vaddr_context;
1674 RegisterInfo reg_info_base;
1675 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1679 // read base register
1680 uint32_t base_address = ReadRegisterUnsigned(
1681 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1685 base_address = base_address + imm5;
1687 // We use bad_vaddr_context to store base address which is used by H/W
1689 // Set the bad_vaddr register with base address used in the instruction
1690 bad_vaddr_context.type = eContextInvalid;
1691 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1694 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1695 RegisterValue data_src;
1696 RegisterInfo reg_info_src;
1698 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1703 context.type = eContextPopRegisterOffStack;
1704 context.SetAddress(base_address);
1706 if (!WriteRegister(context, ®_info_src, data_src))
1715 /* Emulate LWM16, LWM32 and LWP instructions.
1717 LWM16 always has stack pointer as a base register (but it is still available
1718 in MCInst as an operand).
1719 LWM32 and LWP can have base register other than stack pointer.
1721 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1722 bool success = false;
1724 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1725 // no of regs to store.
1726 uint32_t imm = insn.getOperand(num_operands - 1)
1727 .getImm(); // imm is the last operand in the instruction.
1729 // Base register is second last operand of the instruction.
1731 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1733 // We are looking for sp based loads so if base is not a stack pointer then
1735 if (base != dwarf_sp_mips)
1738 uint32_t base_address = ReadRegisterUnsigned(
1739 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1743 base_address = base_address + imm;
1745 RegisterValue data_dst;
1746 RegisterInfo reg_info_dst;
1748 // Total no of registers to be re-stored are num_operands-2.
1749 for (uint32_t i = 0; i < num_operands - 2; i++) {
1750 // Get the register number to be re-stored.
1751 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1754 Record only non-volatile loads.
1755 This check is required for LWP instruction because destination operand
1756 could be any register.
1757 LWM16 and LWM32 instruction always has saved registers as destination
1760 if (!nonvolatile_reg_p(dst))
1763 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
1768 context.type = eContextPopRegisterOffStack;
1769 context.SetAddress(base_address + (i * 4));
1771 if (!WriteRegister(context, ®_info_dst, data_dst))
1778 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1779 bool success = false;
1780 int32_t imm5 = insn.getOperand(0).getImm();
1782 /* JRADDIUSP immediate
1784 * SP <- SP + zero_extend(Immediate << 2)
1787 // This instruction operates implicitly on stack pointer, so read <sp>
1789 int32_t src_opd_val =
1790 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1795 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1799 int32_t result = src_opd_val + imm5;
1804 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1808 RegisterInfo reg_info_sp;
1809 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1810 context.SetRegisterPlusOffset(reg_info_sp, imm5);
1812 // We are adjusting stack
1813 context.type = eContextAdjustStackPointer;
1816 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1823 static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1824 int32_t r = (uint32_t)a + (uint32_t)b;
1825 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1829 Emulate below MIPS branch instructions.
1830 BEQ, BNE : Branch on condition
1831 BEQL, BNEL : Branch likely
1833 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1834 bool success = false;
1836 int32_t offset, pc, target = 0, rs_val, rt_val;
1837 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1839 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1840 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1841 offset = insn.getOperand(2).getImm();
1843 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1847 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1848 dwarf_zero_mips + rs, 0, &success);
1852 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1853 dwarf_zero_mips + rt, 0, &success);
1857 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1858 if (rs_val == rt_val)
1859 target = pc + offset;
1862 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1863 if (rs_val != rt_val)
1864 target = pc + offset;
1870 context.type = eContextRelativeBranchImmediate;
1871 context.SetImmediate(offset);
1873 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1881 Emulate below MIPS branch instructions.
1882 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1883 instructions with no delay slot
1885 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1886 bool success = false;
1888 int32_t offset, pc, target = 0, rs_val, rt_val;
1889 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1890 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1892 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1893 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1894 offset = insn.getOperand(2).getImm();
1896 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1900 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1901 dwarf_zero_mips + rs, 0, &success);
1905 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1906 dwarf_zero_mips + rt, 0, &success);
1910 if (!strcasecmp(op_name, "BEQC")) {
1911 if (rs_val == rt_val)
1912 target = pc + offset;
1915 } else if (!strcasecmp(op_name, "BNEC")) {
1916 if (rs_val != rt_val)
1917 target = pc + offset;
1920 } else if (!strcasecmp(op_name, "BLTC")) {
1921 if (rs_val < rt_val)
1922 target = pc + offset;
1925 } else if (!strcasecmp(op_name, "BGEC")) {
1926 if (rs_val >= rt_val)
1927 target = pc + offset;
1930 } else if (!strcasecmp(op_name, "BLTUC")) {
1931 if (rs_val < rt_val)
1932 target = pc + offset;
1935 } else if (!strcasecmp(op_name, "BGEUC")) {
1936 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1937 target = pc + offset;
1940 } else if (!strcasecmp(op_name, "BOVC")) {
1941 if (IsAdd64bitOverflow(rs_val, rt_val))
1942 target = pc + offset;
1945 } else if (!strcasecmp(op_name, "BNVC")) {
1946 if (!IsAdd64bitOverflow(rs_val, rt_val))
1947 target = pc + offset;
1953 context.type = eContextRelativeBranchImmediate;
1954 context.SetImmediate(current_inst_size + offset);
1956 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1964 Emulate below MIPS conditional branch and link instructions.
1965 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1967 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1968 bool success = false;
1970 int32_t offset, pc, target = 0;
1972 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1974 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1975 offset = insn.getOperand(1).getImm();
1977 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1981 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1982 dwarf_zero_mips + rs, 0, &success);
1986 if (!strcasecmp(op_name, "BLEZALC")) {
1988 target = pc + offset;
1991 } else if (!strcasecmp(op_name, "BGEZALC")) {
1993 target = pc + offset;
1996 } else if (!strcasecmp(op_name, "BLTZALC")) {
1998 target = pc + offset;
2001 } else if (!strcasecmp(op_name, "BGTZALC")) {
2003 target = pc + offset;
2006 } else if (!strcasecmp(op_name, "BEQZALC")) {
2008 target = pc + offset;
2011 } else if (!strcasecmp(op_name, "BNEZALC")) {
2013 target = pc + offset;
2020 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2024 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2032 Emulate below MIPS Non-Compact conditional branch and link instructions.
2034 BLTZALL, BGEZALL : Branch likely
2036 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
2037 bool success = false;
2039 int32_t offset, pc, target = 0;
2041 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2043 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2044 offset = insn.getOperand(1).getImm();
2046 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2050 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2051 dwarf_zero_mips + rs, 0, &success);
2055 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
2056 if ((int32_t)rs_val < 0)
2057 target = pc + offset;
2060 } else if (!strcasecmp(op_name, "BGEZAL") ||
2061 !strcasecmp(op_name, "BGEZALL")) {
2062 if ((int32_t)rs_val >= 0)
2063 target = pc + offset;
2070 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2074 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2082 Emulate below MIPS branch instructions.
2083 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2084 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2086 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2087 bool success = false;
2089 int32_t offset, pc, target = 0;
2091 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2093 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2094 offset = insn.getOperand(1).getImm();
2096 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2100 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2101 dwarf_zero_mips + rs, 0, &success);
2105 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
2107 target = pc + offset;
2110 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
2112 target = pc + offset;
2115 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
2117 target = pc + offset;
2120 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
2122 target = pc + offset;
2128 context.type = eContextRelativeBranchImmediate;
2129 context.SetImmediate(offset);
2131 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2139 Emulate below MIPS branch instructions.
2140 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2142 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2143 bool success = false;
2145 int32_t offset, pc, target = 0;
2147 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2148 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2150 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2151 offset = insn.getOperand(1).getImm();
2153 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2157 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2158 dwarf_zero_mips + rs, 0, &success);
2162 if (!strcasecmp(op_name, "BLTZC")) {
2164 target = pc + offset;
2167 } else if (!strcasecmp(op_name, "BLEZC")) {
2169 target = pc + offset;
2172 } else if (!strcasecmp(op_name, "BGEZC")) {
2174 target = pc + offset;
2177 } else if (!strcasecmp(op_name, "BGTZC")) {
2179 target = pc + offset;
2182 } else if (!strcasecmp(op_name, "BEQZC")) {
2184 target = pc + offset;
2187 } else if (!strcasecmp(op_name, "BNEZC")) {
2189 target = pc + offset;
2195 context.type = eContextRelativeBranchImmediate;
2196 context.SetImmediate(current_inst_size + offset);
2198 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2205 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2206 bool success = false;
2207 int32_t offset, pc, target;
2208 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2210 offset = insn.getOperand(0).getImm();
2212 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2216 // unconditional branch
2217 target = pc + offset;
2220 context.type = eContextRelativeBranchImmediate;
2221 context.SetImmediate(current_inst_size + offset);
2223 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2231 BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2232 BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2233 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2235 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2236 bool success = false;
2238 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2239 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2240 bool update_ra = false;
2241 uint32_t ra_offset = 0;
2245 * condition <- (GPR[rs] = 0)
2247 * PC = PC + sign_ext (offset || 0)
2250 * condition <- (GPR[rs] != 0)
2252 * PC = PC + sign_ext (offset || 0)
2254 * BEQZC rs, offset (compact instruction: No delay slot)
2255 * condition <- (GPR[rs] == 0)
2257 * PC = PC + 4 + sign_ext (offset || 0)
2260 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2261 int32_t offset = insn.getOperand(1).getImm();
2264 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2268 int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2269 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2273 if (!strcasecmp(op_name, "BEQZ16_MM")) {
2275 target = pc + offset;
2277 target = pc + current_inst_size +
2278 m_next_inst_size; // Skip delay slot instruction.
2279 } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
2281 target = pc + offset;
2283 target = pc + current_inst_size +
2284 m_next_inst_size; // Skip delay slot instruction.
2285 } else if (!strcasecmp(op_name, "BEQZC_MM")) {
2287 target = pc + 4 + offset;
2291 4; // 32 bit instruction and does not have delay slot instruction.
2292 } else if (!strcasecmp(op_name, "BNEZC_MM")) {
2294 target = pc + 4 + offset;
2298 4; // 32 bit instruction and does not have delay slot instruction.
2299 } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
2301 target = pc + offset;
2303 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2307 } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
2309 target = pc + offset;
2311 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2318 context.type = eContextRelativeBranchImmediate;
2319 context.SetImmediate(current_inst_size + offset);
2321 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2326 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2333 /* Emulate micromips jump instructions.
2336 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2337 bool success = false;
2338 uint32_t ra_offset = 0;
2339 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2341 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2344 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2348 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2349 dwarf_zero_mips + rs, 0, &success);
2353 if (!strcasecmp(op_name, "JALR16_MM"))
2354 ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2355 else if (!strcasecmp(op_name, "JALRS16_MM"))
2356 ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2360 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2364 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2371 /* Emulate JALS and JALX instructions.
2372 JALS 32 bit instruction with short (2-byte) delay slot.
2373 JALX 32 bit instruction with 4-byte delay slot.
2375 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2376 bool success = false;
2377 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2378 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2383 * offset = sign_ext (offset << 1)
2384 * PC = PC[31-27] | offset
2387 * offset = sign_ext (offset << 2)
2388 * PC = PC[31-28] | offset
2390 offset = insn.getOperand(0).getImm();
2392 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2396 // These are PC-region branches and not PC-relative.
2397 if (!strcasecmp(op_name, "JALS_MM")) {
2398 // target address is in the “current” 128 MB-aligned region
2399 target = (pc & 0xF8000000UL) | offset;
2401 } else if (!strcasecmp(op_name, "JALX_MM")) {
2402 // target address is in the “current” 256 MB-aligned region
2403 target = (pc & 0xF0000000UL) | offset;
2409 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2413 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2420 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2421 bool success = false;
2422 uint32_t rs = 0, rt = 0;
2423 int32_t pc = 0, rs_val = 0;
2431 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2432 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2434 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2435 dwarf_zero_mips + rs, 0, &success);
2439 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2445 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2449 // This is 4-byte instruction with 2-byte delay slot.
2450 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2457 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2458 bool success = false;
2459 int32_t offset, pc, target;
2463 * offset = sign_ext (offset << 2)
2467 offset = insn.getOperand(0).getImm();
2469 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2473 target = pc + offset;
2477 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2481 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2488 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2489 bool success = false;
2490 int32_t offset, pc, target;
2494 * offset = sign_ext (offset << 2)
2496 * PC = PC + 4 + offset
2498 offset = insn.getOperand(0).getImm();
2500 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2504 target = pc + offset;
2508 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2512 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2519 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2520 bool success = false;
2521 int32_t offset, pc, target;
2525 * offset = sign_ext (offset << 2)
2526 * PC = PC + 4 + offset
2528 offset = insn.getOperand(0).getImm();
2530 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2534 target = pc + offset;
2538 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2545 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2546 bool success = false;
2547 uint32_t offset, pc;
2551 * offset = sign_ext (offset << 2)
2552 * PC = PC[63-28] | offset
2554 offset = insn.getOperand(0).getImm();
2556 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2560 /* This is a PC-region branch and not PC-relative */
2561 pc = (pc & 0xF0000000UL) | offset;
2565 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc))
2571 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2572 bool success = false;
2573 uint32_t offset, target, pc;
2577 * offset = sign_ext (offset << 2)
2578 * PC = PC[63-28] | offset
2580 offset = insn.getOperand(0).getImm();
2582 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2586 /* This is a PC-region branch and not PC-relative */
2587 target = (pc & 0xF0000000UL) | offset;
2591 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2595 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2602 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2603 bool success = false;
2605 uint32_t pc, rs_val;
2612 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2613 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2615 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2619 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2626 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2630 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2637 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2638 bool success = false;
2640 int32_t target, offset, pc, rt_val;
2644 * offset = sign_ext (offset)
2645 * PC = GPR[rt] + offset
2648 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2649 offset = insn.getOperand(1).getImm();
2651 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2655 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2656 dwarf_zero_mips + rt, 0, &success);
2660 target = rt_val + offset;
2664 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2668 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2675 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2676 bool success = false;
2678 int32_t target, offset, rt_val;
2682 * offset = sign_ext (offset)
2683 * PC = GPR[rt] + offset
2685 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2686 offset = insn.getOperand(1).getImm();
2688 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2689 dwarf_zero_mips + rt, 0, &success);
2693 target = rt_val + offset;
2697 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2704 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2705 bool success = false;
2713 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2715 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2722 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2730 Emulate Branch on FP True/False
2731 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2732 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2734 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2735 bool success = false;
2737 int32_t pc, offset, target = 0;
2738 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2740 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2741 offset = insn.getOperand(1).getImm();
2743 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2747 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2751 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2752 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2754 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2755 if ((fcsr & (1 << cc)) == 0)
2756 target = pc + offset;
2759 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2760 if ((fcsr & (1 << cc)) != 0)
2761 target = pc + offset;
2767 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2774 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2775 bool success = false;
2778 int32_t target, pc, offset;
2782 * condition <- (FPR[ft].bit0 == 0)
2784 * offset = sign_ext (offset)
2785 * PC = PC + 4 + offset
2787 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2788 offset = insn.getOperand(1).getImm();
2790 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2794 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2799 if ((ft_val & 1) == 0)
2800 target = pc + 4 + offset;
2806 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2813 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2814 bool success = false;
2817 int32_t target, pc, offset;
2821 * condition <- (FPR[ft].bit0 != 0)
2823 * offset = sign_ext (offset)
2824 * PC = PC + 4 + offset
2826 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2827 offset = insn.getOperand(1).getImm();
2829 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2833 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2838 if ((ft_val & 1) != 0)
2839 target = pc + 4 + offset;
2845 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2853 Emulate MIPS-3D Branch instructions
2854 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2856 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2859 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2860 bool success = false;
2862 int32_t pc, offset, target = 0;
2863 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2865 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2866 offset = insn.getOperand(1).getImm();
2868 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2872 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2877 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2878 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2880 if (!strcasecmp(op_name, "BC1ANY2F")) {
2881 /* if any one bit is 0 */
2882 if (((fcsr >> cc) & 3) != 3)
2883 target = pc + offset;
2886 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2887 /* if any one bit is 1 */
2888 if (((fcsr >> cc) & 3) != 0)
2889 target = pc + offset;
2892 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2893 /* if any one bit is 0 */
2894 if (((fcsr >> cc) & 0xf) != 0xf)
2895 target = pc + offset;
2898 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2899 /* if any one bit is 1 */
2900 if (((fcsr >> cc) & 0xf) != 0)
2901 target = pc + offset;
2907 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2914 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2915 return Emulate_MSA_Branch_DF(insn, 1, true);
2918 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2919 return Emulate_MSA_Branch_DF(insn, 2, true);
2922 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2923 return Emulate_MSA_Branch_DF(insn, 4, true);
2926 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2927 return Emulate_MSA_Branch_DF(insn, 8, true);
2930 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2931 return Emulate_MSA_Branch_DF(insn, 1, false);
2934 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2935 return Emulate_MSA_Branch_DF(insn, 2, false);
2938 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2939 return Emulate_MSA_Branch_DF(insn, 4, false);
2942 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2943 return Emulate_MSA_Branch_DF(insn, 8, false);
2946 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2947 int element_byte_size,
2949 bool success = false, branch_hit = true;
2951 RegisterValue reg_value;
2952 const uint8_t *ptr = NULL;
2954 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2955 int32_t offset = insn.getOperand(1).getImm();
2958 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2962 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2963 ptr = (const uint8_t *)reg_value.GetBytes();
2967 for (int i = 0; i < 16 / element_byte_size; i++) {
2968 switch (element_byte_size) {
2970 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2974 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2975 (*(const uint16_t *)ptr != 0 && !bnz))
2979 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2980 (*(const uint32_t *)ptr != 0 && !bnz))
2984 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2985 (*(const uint64_t *)ptr != 0 && !bnz))
2991 ptr = ptr + element_byte_size;
2995 target = pc + offset;
3000 context.type = eContextRelativeBranchImmediate;
3002 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
3009 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
3010 return Emulate_MSA_Branch_V(insn, true);
3013 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
3014 return Emulate_MSA_Branch_V(insn, false);
3017 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
3019 bool success = false;
3021 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
3022 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
3023 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
3024 RegisterValue reg_value;
3026 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
3027 int32_t offset = insn.getOperand(1).getImm();
3030 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
3034 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
3035 wr_val = reg_value.GetAsUInt128(fail_value);
3039 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
3040 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
3041 target = pc + offset;
3046 context.type = eContextRelativeBranchImmediate;
3048 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
3055 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
3056 bool success = false;
3058 int32_t imm, address;
3059 Context bad_vaddr_context;
3061 uint32_t num_operands = insn.getNumOperands();
3063 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3064 imm = insn.getOperand(num_operands - 1).getImm();
3066 RegisterInfo reg_info_base;
3067 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3071 /* read base register */
3072 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3073 dwarf_zero_mips + base, 0, &success);
3077 /* destination address */
3078 address = address + imm;
3080 /* Set the bad_vaddr register with base address used in the instruction */
3081 bad_vaddr_context.type = eContextInvalid;
3082 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3088 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3089 bool success = false;
3090 uint32_t base, index;
3091 int32_t address, index_address;
3092 Context bad_vaddr_context;
3094 uint32_t num_operands = insn.getNumOperands();
3096 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3098 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3100 RegisterInfo reg_info_base, reg_info_index;
3101 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3105 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
3109 /* read base register */
3110 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3111 dwarf_zero_mips + base, 0, &success);
3115 /* read index register */
3116 index_address = (int32_t)ReadRegisterUnsigned(
3117 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3121 /* destination address */
3122 address = address + index_address;
3124 /* Set the bad_vaddr register with base address used in the instruction */
3125 bad_vaddr_context.type = eContextInvalid;
3126 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,