1 //===-- EmulateInstructionMIPS.cpp ----------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "EmulateInstructionMIPS.h"
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/MC/MCTargetOptions.h"
33 #include "llvm/MC/TargetRegistry.h"
34 #include "llvm/Support/TargetSelect.h"
36 #include "llvm/ADT/STLExtras.h"
38 #include "Plugins/Process/Utility/InstructionUtils.h"
39 #include "Plugins/Process/Utility/RegisterContext_mips.h"
42 using namespace lldb_private
;
44 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS
, InstructionMIPS
)
46 #define UInt(x) ((uint64_t)x)
47 #define integer int64_t
50 // EmulateInstructionMIPS implementation
55 void LLVMInitializeMipsTargetInfo();
56 void LLVMInitializeMipsTarget();
57 void LLVMInitializeMipsAsmPrinter();
58 void LLVMInitializeMipsTargetMC();
59 void LLVMInitializeMipsDisassembler();
63 EmulateInstructionMIPS::EmulateInstructionMIPS(
64 const lldb_private::ArchSpec
&arch
)
65 : EmulateInstruction(arch
) {
66 /* Create instance of llvm::MCDisassembler */
68 llvm::Triple triple
= arch
.GetTriple();
69 const llvm::Target
*target
=
70 llvm::TargetRegistry::lookupTarget(triple
.getTriple(), Status
);
73 * If we fail to get the target then we haven't registered it. The
74 * SystemInitializerCommon
75 * does not initialize targets, MCs and disassemblers. However we need the
77 * to decode the instructions so that the decoding complexity stays with LLVM.
78 * Initialize the MIPS targets and disassemblers.
82 LLVMInitializeMipsTargetInfo();
83 LLVMInitializeMipsTarget();
84 LLVMInitializeMipsAsmPrinter();
85 LLVMInitializeMipsTargetMC();
86 LLVMInitializeMipsDisassembler();
87 target
= llvm::TargetRegistry::lookupTarget(triple
.getTriple(), Status
);
95 switch (arch
.GetCore()) {
96 case ArchSpec::eCore_mips32
:
97 case ArchSpec::eCore_mips32el
:
100 case ArchSpec::eCore_mips32r2
:
101 case ArchSpec::eCore_mips32r2el
:
104 case ArchSpec::eCore_mips32r3
:
105 case ArchSpec::eCore_mips32r3el
:
108 case ArchSpec::eCore_mips32r5
:
109 case ArchSpec::eCore_mips32r5el
:
112 case ArchSpec::eCore_mips32r6
:
113 case ArchSpec::eCore_mips32r6el
:
116 case ArchSpec::eCore_mips64
:
117 case ArchSpec::eCore_mips64el
:
120 case ArchSpec::eCore_mips64r2
:
121 case ArchSpec::eCore_mips64r2el
:
124 case ArchSpec::eCore_mips64r3
:
125 case ArchSpec::eCore_mips64r3el
:
128 case ArchSpec::eCore_mips64r5
:
129 case ArchSpec::eCore_mips64r5el
:
132 case ArchSpec::eCore_mips64r6
:
133 case ArchSpec::eCore_mips64r6el
:
141 std::string features
;
142 uint32_t arch_flags
= arch
.GetFlags();
143 if (arch_flags
& ArchSpec::eMIPSAse_msa
)
145 if (arch_flags
& ArchSpec::eMIPSAse_dsp
)
147 if (arch_flags
& ArchSpec::eMIPSAse_dspr2
)
148 features
+= "+dspr2,";
150 m_reg_info
.reset(target
->createMCRegInfo(triple
.getTriple()));
151 assert(m_reg_info
.get());
153 m_insn_info
.reset(target
->createMCInstrInfo());
154 assert(m_insn_info
.get());
156 llvm::MCTargetOptions MCOptions
;
158 target
->createMCAsmInfo(*m_reg_info
, triple
.getTriple(), MCOptions
));
159 m_subtype_info
.reset(
160 target
->createMCSubtargetInfo(triple
.getTriple(), cpu
, features
));
161 assert(m_asm_info
.get() && m_subtype_info
.get());
163 m_context
= std::make_unique
<llvm::MCContext
>(
164 triple
, m_asm_info
.get(), m_reg_info
.get(), m_subtype_info
.get());
165 assert(m_context
.get());
167 m_disasm
.reset(target
->createMCDisassembler(*m_subtype_info
, *m_context
));
168 assert(m_disasm
.get());
170 /* Create alternate disassembler for microMIPS */
171 if (arch_flags
& ArchSpec::eMIPSAse_mips16
)
172 features
+= "+mips16,";
173 else if (arch_flags
& ArchSpec::eMIPSAse_micromips
)
174 features
+= "+micromips,";
176 m_alt_subtype_info
.reset(
177 target
->createMCSubtargetInfo(triple
.getTriple(), cpu
, features
));
178 assert(m_alt_subtype_info
.get());
181 target
->createMCDisassembler(*m_alt_subtype_info
, *m_context
));
182 assert(m_alt_disasm
.get());
184 m_next_inst_size
= 0;
185 m_use_alt_disaasm
= false;
188 void EmulateInstructionMIPS::Initialize() {
189 PluginManager::RegisterPlugin(GetPluginNameStatic(),
190 GetPluginDescriptionStatic(), CreateInstance
);
193 void EmulateInstructionMIPS::Terminate() {
194 PluginManager::UnregisterPlugin(CreateInstance
);
197 llvm::StringRef
EmulateInstructionMIPS::GetPluginDescriptionStatic() {
198 return "Emulate instructions for the MIPS32 architecture.";
202 EmulateInstructionMIPS::CreateInstance(const ArchSpec
&arch
,
203 InstructionType inst_type
) {
204 if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
206 if (arch
.GetTriple().getArch() == llvm::Triple::mips
||
207 arch
.GetTriple().getArch() == llvm::Triple::mipsel
) {
208 return new EmulateInstructionMIPS(arch
);
215 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec
&arch
) {
216 return arch
.GetTriple().getArch() == llvm::Triple::mips
||
217 arch
.GetTriple().getArch() == llvm::Triple::mipsel
;
220 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num
,
221 bool alternate_name
) {
222 if (alternate_name
) {
360 case dwarf_mcsr_mips
:
362 case dwarf_config5_mips
:
371 case dwarf_zero_mips
:
443 case dwarf_cause_mips
:
511 case dwarf_fcsr_mips
:
579 case dwarf_mcsr_mips
:
583 case dwarf_config5_mips
:
589 std::optional
<RegisterInfo
>
590 EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind
,
592 if (reg_kind
== eRegisterKindGeneric
) {
594 case LLDB_REGNUM_GENERIC_PC
:
595 reg_kind
= eRegisterKindDWARF
;
596 reg_num
= dwarf_pc_mips
;
598 case LLDB_REGNUM_GENERIC_SP
:
599 reg_kind
= eRegisterKindDWARF
;
600 reg_num
= dwarf_sp_mips
;
602 case LLDB_REGNUM_GENERIC_FP
:
603 reg_kind
= eRegisterKindDWARF
;
604 reg_num
= dwarf_r30_mips
;
606 case LLDB_REGNUM_GENERIC_RA
:
607 reg_kind
= eRegisterKindDWARF
;
608 reg_num
= dwarf_ra_mips
;
610 case LLDB_REGNUM_GENERIC_FLAGS
:
611 reg_kind
= eRegisterKindDWARF
;
612 reg_num
= dwarf_sr_mips
;
619 if (reg_kind
== eRegisterKindDWARF
) {
620 RegisterInfo reg_info
;
621 ::memset(®_info
, 0, sizeof(RegisterInfo
));
622 ::memset(reg_info
.kinds
, LLDB_INVALID_REGNUM
, sizeof(reg_info
.kinds
));
624 if (reg_num
== dwarf_sr_mips
|| reg_num
== dwarf_fcsr_mips
||
625 reg_num
== dwarf_fir_mips
|| reg_num
== dwarf_mcsr_mips
||
626 reg_num
== dwarf_mir_mips
|| reg_num
== dwarf_config5_mips
) {
627 reg_info
.byte_size
= 4;
628 reg_info
.format
= eFormatHex
;
629 reg_info
.encoding
= eEncodingUint
;
630 } else if ((int)reg_num
>= dwarf_zero_mips
&&
631 (int)reg_num
<= dwarf_f31_mips
) {
632 reg_info
.byte_size
= 4;
633 reg_info
.format
= eFormatHex
;
634 reg_info
.encoding
= eEncodingUint
;
635 } else if ((int)reg_num
>= dwarf_w0_mips
&&
636 (int)reg_num
<= dwarf_w31_mips
) {
637 reg_info
.byte_size
= 16;
638 reg_info
.format
= eFormatVectorOfUInt8
;
639 reg_info
.encoding
= eEncodingVector
;
644 reg_info
.name
= GetRegisterName(reg_num
, false);
645 reg_info
.alt_name
= GetRegisterName(reg_num
, true);
646 reg_info
.kinds
[eRegisterKindDWARF
] = reg_num
;
650 reg_info
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
653 reg_info
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_RA
;
656 reg_info
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_SP
;
659 reg_info
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_PC
;
662 reg_info
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FLAGS
;
672 EmulateInstructionMIPS::MipsOpcode
*
673 EmulateInstructionMIPS::GetOpcodeForInstruction(llvm::StringRef name
) {
674 static EmulateInstructionMIPS::MipsOpcode g_opcodes
[] = {
675 // Prologue/Epilogue instructions
676 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu
,
677 "ADDIU rt, rs, immediate"},
678 {"SW", &EmulateInstructionMIPS::Emulate_SW
, "SW rt, offset(rs)"},
679 {"LW", &EmulateInstructionMIPS::Emulate_LW
, "LW rt, offset(base)"},
680 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU
, "SUBU rd, rs, rt"},
681 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU
, "ADDU rd, rs, rt"},
682 {"LUI", &EmulateInstructionMIPS::Emulate_LUI
, "LUI rt, immediate"},
684 // MicroMIPS Prologue/Epilogue instructions
685 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP
,
687 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5
,
688 "ADDIUS5 rd,immediate"},
689 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP
, "SWSP rt,offset(sp)"},
690 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32
,
691 "SWM16 reglist,offset(sp)"},
692 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32
,
693 "SWM32 reglist,offset(base)"},
694 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32
,
695 "SWP rs1,offset(base)"},
696 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP
, "LWSP rt,offset(sp)"},
697 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32
,
698 "LWM16 reglist,offset(sp)"},
699 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32
,
700 "LWM32 reglist,offset(base)"},
701 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32
,
702 "LWP rd,offset(base)"},
703 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP
,
704 "JRADDIUSP immediate"},
706 // Load/Store instructions
707 /* Following list of emulated instructions are required by implementation
708 of hardware watchpoint
709 for MIPS in lldb. As we just need the address accessed by instructions,
711 all these instructions in 2 functions depending on their addressing
714 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
715 "LB rt, offset(base)"},
716 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
717 "LBE rt, offset(base)"},
718 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
719 "LBU rt, offset(base)"},
720 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
721 "LBUE rt, offset(base)"},
722 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
723 "LDC1 ft, offset(base)"},
724 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
725 "LD rt, offset(base)"},
726 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
727 "LDL rt, offset(base)"},
728 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
729 "LDR rt, offset(base)"},
730 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
731 "LLD rt, offset(base)"},
732 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
733 "LDC2 rt, offset(base)"},
734 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg
,
735 "LDXC1 fd, index (base)"},
736 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
737 "LH rt, offset(base)"},
738 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
739 "LHE rt, offset(base)"},
740 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
741 "LHU rt, offset(base)"},
742 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
743 "LHUE rt, offset(base)"},
744 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
745 "LL rt, offset(base)"},
746 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
747 "LLE rt, offset(base)"},
748 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg
,
749 "LUXC1 fd, index (base)"},
750 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
751 "LW rt, offset(base)"},
752 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
753 "LWC1 ft, offset(base)"},
754 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
755 "LWC2 rt, offset(base)"},
756 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
757 "LWE rt, offset(base)"},
758 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
759 "LWL rt, offset(base)"},
760 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
761 "LWLE rt, offset(base)"},
762 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
763 "LWR rt, offset(base)"},
764 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
765 "LWRE rt, offset(base)"},
766 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg
,
767 "LWXC1 fd, index (base)"},
768 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
769 "LLX rt, offset(base)"},
770 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
771 "LLXE rt, offset(base)"},
772 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
773 "LLDX rt, offset(base)"},
775 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
776 "SB rt, offset(base)"},
777 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
778 "SBE rt, offset(base)"},
779 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
780 "SC rt, offset(base)"},
781 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
782 "SCE rt, offset(base)"},
783 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
784 "SCD rt, offset(base)"},
785 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
786 "SD rt, offset(base)"},
787 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
788 "SDL rt, offset(base)"},
789 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
790 "SDR rt, offset(base)"},
791 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
792 "SDC1 ft, offset(base)"},
793 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
794 "SDC2 rt, offset(base)"},
795 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg
,
796 "SDXC1 fs, index(base)"},
797 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
798 "SH rt, offset(base)"},
799 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
800 "SHE rt, offset(base)"},
801 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg
,
802 "SUXC1 fs, index (base)"},
803 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
804 "SWC1 ft, offset(base)"},
805 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
806 "SWC2 rt, offset(base)"},
807 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
808 "SWE rt, offset(base)"},
809 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
810 "SWL rt, offset(base)"},
811 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
812 "SWLE rt, offset(base)"},
813 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
814 "SWR rt, offset(base)"},
815 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
816 "SWRE rt, offset(base)"},
817 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg
,
818 "SWXC1 fs, index (base)"},
819 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
820 "SCX rt, offset(base)"},
821 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
822 "SCXE rt, offset(base)"},
823 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
824 "SCDX rt, offset(base)"},
826 // MicroMIPS Load/Store instructions
827 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
828 "LBU16 rt, decoded_offset(base)"},
829 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
830 "LHU16 rt, left_shifted_offset(base)"},
831 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
832 "LW16 rt, left_shifted_offset(base)"},
833 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
834 "LWGP rt, left_shifted_offset(gp)"},
835 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
836 "SH16 rt, left_shifted_offset(base)"},
837 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
838 "SW16 rt, left_shifted_offset(base)"},
839 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
840 "SWSP rt, left_shifted_offset(base)"},
841 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm
,
842 "SB16 rt, offset(base)"},
844 // Branch instructions
845 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops
, "BEQ rs,rt,offset"},
846 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops
, "BNE rs,rt,offset"},
847 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops
, "BEQL rs,rt,offset"},
848 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops
, "BNEL rs,rt,offset"},
849 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link
,
850 "BGEZALL rt,offset"},
851 {"BAL", &EmulateInstructionMIPS::Emulate_BAL
, "BAL offset"},
852 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link
,
854 {"BALC", &EmulateInstructionMIPS::Emulate_BALC
, "BALC offset"},
855 {"BC", &EmulateInstructionMIPS::Emulate_BC
, "BC offset"},
856 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BGEZ rs,offset"},
857 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C
,
858 "BLEZALC rs,offset"},
859 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C
,
860 "BGEZALC rs,offset"},
861 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C
,
862 "BLTZALC rs,offset"},
863 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C
,
864 "BGTZALC rs,offset"},
865 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C
,
866 "BEQZALC rs,offset"},
867 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C
,
868 "BNEZALC rs,offset"},
869 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
870 "BEQC rs,rt,offset"},
871 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
872 "BNEC rs,rt,offset"},
873 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
874 "BLTC rs,rt,offset"},
875 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
876 "BGEC rs,rt,offset"},
877 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
878 "BLTUC rs,rt,offset"},
879 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
880 "BGEUC rs,rt,offset"},
881 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C
, "BLTZC rt,offset"},
882 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C
, "BLEZC rt,offset"},
883 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C
, "BGEZC rt,offset"},
884 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C
, "BGTZC rt,offset"},
885 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C
, "BEQZC rt,offset"},
886 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C
, "BNEZC rt,offset"},
887 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BGEZL rt,offset"},
888 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BGTZ rt,offset"},
889 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BGTZL rt,offset"},
890 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BLEZ rt,offset"},
891 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BLEZL rt,offset"},
892 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BLTZ rt,offset"},
893 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link
,
895 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link
,
896 "BLTZALL rt,offset"},
897 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops
, "BLTZL rt,offset"},
898 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
899 "BOVC rs,rt,offset"},
900 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C
,
901 "BNVC rs,rt,offset"},
902 {"J", &EmulateInstructionMIPS::Emulate_J
, "J target"},
903 {"JAL", &EmulateInstructionMIPS::Emulate_JAL
, "JAL target"},
904 {"JALX", &EmulateInstructionMIPS::Emulate_JAL
, "JALX target"},
905 {"JALR", &EmulateInstructionMIPS::Emulate_JALR
, "JALR target"},
906 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR
, "JALR.HB target"},
907 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC
, "JIALC rt,offset"},
908 {"JIC", &EmulateInstructionMIPS::Emulate_JIC
, "JIC rt,offset"},
909 {"JR", &EmulateInstructionMIPS::Emulate_JR
, "JR target"},
910 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR
, "JR.HB target"},
911 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch
, "BC1F cc, offset"},
912 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch
, "BC1T cc, offset"},
913 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch
, "BC1FL cc, offset"},
914 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch
, "BC1TL cc, offset"},
915 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ
, "BC1EQZ ft, offset"},
916 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ
, "BC1NEZ ft, offset"},
917 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch
,
918 "BC1ANY2F cc, offset"},
919 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch
,
920 "BC1ANY2T cc, offset"},
921 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch
,
922 "BC1ANY4F cc, offset"},
923 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch
,
924 "BC1ANY4T cc, offset"},
925 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB
, "BNZ.b wt,s16"},
926 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH
, "BNZ.h wt,s16"},
927 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW
, "BNZ.w wt,s16"},
928 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD
, "BNZ.d wt,s16"},
929 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB
, "BZ.b wt,s16"},
930 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH
, "BZ.h wt,s16"},
931 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW
, "BZ.w wt,s16"},
932 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD
, "BZ.d wt,s16"},
933 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV
, "BNZ.V wt,s16"},
934 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV
, "BZ.V wt,s16"},
936 // MicroMIPS Branch instructions
937 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM
, "B16 offset"},
938 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM
,
939 "BEQZ16 rs, offset"},
940 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM
,
941 "BNEZ16 rs, offset"},
942 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM
,
944 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM
,
946 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM
,
947 "BGEZALS rs, offset"},
948 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM
,
949 "BLTZALS rs, offset"},
950 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM
, "JALR16 rs"},
951 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM
, "JALRS16 rs"},
952 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR
, "JR16 rs rs"},
953 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR
, "JRC16 rs rs"},
954 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx
, "JALS target"},
955 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx
, "JALX target"},
956 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS
, "JALRS rt, rs"},
959 for (MipsOpcode
&opcode
: g_opcodes
) {
960 if (name
.equals_insensitive(opcode
.op_name
))
967 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor
&data
,
968 uint64_t inst_addr
) {
969 uint64_t next_inst_size
= 0;
970 llvm::MCInst mc_insn
;
971 llvm::MCDisassembler::DecodeStatus decode_status
;
972 llvm::ArrayRef
<uint8_t> raw_insn(data
.GetDataStart(), data
.GetByteSize());
974 if (m_use_alt_disaasm
)
975 decode_status
= m_alt_disasm
->getInstruction(
976 mc_insn
, next_inst_size
, raw_insn
, inst_addr
, llvm::nulls());
978 decode_status
= m_disasm
->getInstruction(mc_insn
, next_inst_size
, raw_insn
,
979 inst_addr
, llvm::nulls());
981 if (decode_status
!= llvm::MCDisassembler::Success
)
984 return m_insn_info
->get(mc_insn
.getOpcode()).getSize();
987 bool EmulateInstructionMIPS::SetInstruction(const Opcode
&insn_opcode
,
988 const Address
&inst_addr
,
990 m_use_alt_disaasm
= false;
992 if (EmulateInstruction::SetInstruction(insn_opcode
, inst_addr
, target
)) {
993 if (inst_addr
.GetAddressClass() == AddressClass::eCodeAlternateISA
) {
995 lldb::addr_t load_addr
= LLDB_INVALID_ADDRESS
;
998 * The address belongs to microMIPS function. To find the size of
999 * next instruction use microMIPS disassembler.
1001 m_use_alt_disaasm
= true;
1003 uint32_t current_inst_size
= insn_opcode
.GetByteSize();
1004 uint8_t buf
[sizeof(uint32_t)];
1005 uint64_t next_inst_addr
= (m_addr
& (~1ull)) + current_inst_size
;
1006 Address
next_addr(next_inst_addr
);
1008 const size_t bytes_read
=
1009 target
->ReadMemory(next_addr
, /* Address of next instruction */
1010 buf
, sizeof(uint32_t), error
,
1011 false, /* force_live_memory */
1014 if (bytes_read
== 0)
1017 DataExtractor
data(buf
, sizeof(uint32_t), GetByteOrder(),
1018 GetAddressByteSize());
1019 m_next_inst_size
= GetSizeOfInstruction(data
, next_inst_addr
);
1023 * If the address class is not AddressClass::eCodeAlternateISA then
1024 * the function is not microMIPS. In this case instruction size is
1027 m_next_inst_size
= 4;
1034 bool EmulateInstructionMIPS::ReadInstruction() {
1035 bool success
= false;
1036 m_addr
= ReadRegisterUnsigned(eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_PC
,
1037 LLDB_INVALID_ADDRESS
, &success
);
1039 Context read_inst_context
;
1040 read_inst_context
.type
= eContextReadOpcode
;
1041 read_inst_context
.SetNoArgs();
1042 m_opcode
.SetOpcode32(
1043 ReadMemoryUnsigned(read_inst_context
, m_addr
, 4, 0, &success
),
1047 m_addr
= LLDB_INVALID_ADDRESS
;
1051 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options
) {
1052 bool success
= false;
1053 llvm::MCInst mc_insn
;
1057 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1059 if (m_opcode
.GetData(data
)) {
1060 llvm::MCDisassembler::DecodeStatus decode_status
;
1061 llvm::ArrayRef
<uint8_t> raw_insn(data
.GetDataStart(), data
.GetByteSize());
1062 if (m_use_alt_disaasm
)
1063 decode_status
= m_alt_disasm
->getInstruction(mc_insn
, insn_size
, raw_insn
,
1064 m_addr
, llvm::nulls());
1066 decode_status
= m_disasm
->getInstruction(mc_insn
, insn_size
, raw_insn
,
1067 m_addr
, llvm::nulls());
1069 if (decode_status
!= llvm::MCDisassembler::Success
)
1074 * mc_insn.getOpcode() returns decoded opcode. However to make use
1075 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1077 const char *op_name
= m_insn_info
->getName(mc_insn
.getOpcode()).data();
1079 if (op_name
== nullptr)
1083 * Decoding has been done already. Just get the call-back function
1084 * and emulate the instruction.
1086 MipsOpcode
*opcode_data
= GetOpcodeForInstruction(op_name
);
1088 if (opcode_data
== nullptr)
1091 uint64_t old_pc
= 0, new_pc
= 0;
1092 const bool auto_advance_pc
=
1093 evaluate_options
& eEmulateInstructionOptionAutoAdvancePC
;
1095 if (auto_advance_pc
) {
1097 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
1102 /* emulate instruction */
1103 success
= (this->*opcode_data
->callback
)(mc_insn
);
1107 if (auto_advance_pc
) {
1109 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
1113 /* If we haven't changed the PC, change it here */
1114 if (old_pc
== new_pc
) {
1117 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
1126 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1127 UnwindPlan
&unwind_plan
) {
1128 unwind_plan
.Clear();
1129 unwind_plan
.SetRegisterKind(eRegisterKindDWARF
);
1131 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1132 const bool can_replace
= false;
1134 // Our previous Call Frame Address is the stack pointer
1135 row
->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips
, 0);
1137 // Our previous PC is in the RA
1138 row
->SetRegisterLocationToRegister(dwarf_pc_mips
, dwarf_ra_mips
, can_replace
);
1140 unwind_plan
.AppendRow(row
);
1142 // All other registers are the same.
1143 unwind_plan
.SetSourceName("EmulateInstructionMIPS");
1144 unwind_plan
.SetSourcedFromCompiler(eLazyBoolNo
);
1145 unwind_plan
.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes
);
1146 unwind_plan
.SetUnwindPlanForSignalTrap(eLazyBoolNo
);
1147 unwind_plan
.SetReturnAddressRegister(dwarf_ra_mips
);
1152 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum
) {
1154 case dwarf_r16_mips
:
1155 case dwarf_r17_mips
:
1156 case dwarf_r18_mips
:
1157 case dwarf_r19_mips
:
1158 case dwarf_r20_mips
:
1159 case dwarf_r21_mips
:
1160 case dwarf_r22_mips
:
1161 case dwarf_r23_mips
:
1164 case dwarf_r30_mips
:
1173 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst
&insn
) {
1174 // ADDIU rt, rs, immediate
1175 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1178 bool success
= false;
1179 const uint32_t imm16
= insn
.getOperand(2).getImm();
1180 int64_t imm
= SignedBits(imm16
, 15, 0);
1182 dst
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1183 src
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1185 // If immediate value is greater then 2^16 - 1 then clang generate LUI,
1186 // ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1,
1187 // -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same
1188 // and not equal to sp
1192 /* read <src> register */
1193 const int64_t src_opd_val
= ReadRegisterUnsigned(
1194 eRegisterKindDWARF
, dwarf_zero_mips
+ src
, 0, &success
);
1198 /* Check if this is daddiu sp, sp, imm16 */
1199 if (dst
== dwarf_sp_mips
) {
1200 uint64_t result
= src_opd_val
+ imm
;
1201 std::optional
<RegisterInfo
> reg_info_sp
=
1202 GetRegisterInfo(eRegisterKindDWARF
, dwarf_sp_mips
);
1204 context
.SetRegisterPlusOffset(*reg_info_sp
, imm
);
1206 /* We are allocating bytes on stack */
1207 context
.type
= eContextAdjustStackPointer
;
1209 WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_sp_mips
, result
);
1214 context
.SetImmediateSigned(imm
);
1215 context
.type
= eContextImmediate
;
1217 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
,
1218 dwarf_zero_mips
+ dst
, imm
))
1225 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst
&insn
) {
1226 bool success
= false;
1227 uint32_t imm16
= insn
.getOperand(2).getImm();
1228 uint32_t imm
= SignedBits(imm16
, 15, 0);
1231 Context bad_vaddr_context
;
1233 src
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1234 base
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1236 std::optional
<RegisterInfo
> reg_info_base
=
1237 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
);
1241 /* read base register */
1242 address
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1243 dwarf_zero_mips
+ base
, 0, &success
);
1247 /* destination address */
1248 address
= address
+ imm
;
1250 /* Set the bad_vaddr register with base address used in the instruction */
1251 bad_vaddr_context
.type
= eContextInvalid
;
1252 WriteRegisterUnsigned(bad_vaddr_context
, eRegisterKindDWARF
, dwarf_bad_mips
,
1255 /* We look for sp based non-volatile register stores */
1256 if (nonvolatile_reg_p(src
)) {
1257 std::optional
<RegisterInfo
> reg_info_src
=
1258 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ src
);
1263 context
.type
= eContextPushRegisterOnStack
;
1264 context
.SetRegisterToRegisterPlusOffset(*reg_info_src
, *reg_info_base
, 0);
1266 RegisterValue::BytesContainer
buffer(reg_info_src
->byte_size
);
1269 std::optional
<RegisterValue
> data_src
= ReadRegister(*reg_info_base
);
1273 if (data_src
->GetAsMemoryData(*reg_info_src
, buffer
.data(),
1274 reg_info_src
->byte_size
, eByteOrderLittle
,
1278 if (!WriteMemory(context
, address
, buffer
.data(), reg_info_src
->byte_size
))
1287 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst
&insn
) {
1288 bool success
= false;
1290 int32_t imm
, address
;
1291 Context bad_vaddr_context
;
1293 src
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1294 base
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1295 imm
= insn
.getOperand(2).getImm();
1297 if (GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
))
1300 /* read base register */
1301 address
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1302 dwarf_zero_mips
+ base
, 0, &success
);
1306 /* destination address */
1307 address
= address
+ imm
;
1309 /* Set the bad_vaddr register with base address used in the instruction */
1310 bad_vaddr_context
.type
= eContextInvalid
;
1311 WriteRegisterUnsigned(bad_vaddr_context
, eRegisterKindDWARF
, dwarf_bad_mips
,
1314 if (nonvolatile_reg_p(src
)) {
1315 RegisterValue data_src
;
1316 std::optional
<RegisterInfo
> reg_info_src
=
1317 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ src
);
1322 context
.type
= eContextPopRegisterOffStack
;
1323 context
.SetAddress(address
);
1325 return WriteRegister(context
, *reg_info_src
, data_src
);
1331 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst
&insn
) {
1332 // SUBU sp, <src>, <rt>
1333 // ADDU sp, <src>, <rt>
1334 // ADDU dst, sp, <rt>
1336 bool success
= false;
1338 uint8_t src
, dst
, rt
;
1339 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
1341 dst
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1342 src
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1344 /* Check if sp is destination register */
1345 if (dst
== dwarf_sp_mips
) {
1346 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(2).getReg());
1348 /* read <src> register */
1349 uint64_t src_opd_val
= ReadRegisterUnsigned(
1350 eRegisterKindDWARF
, dwarf_zero_mips
+ src
, 0, &success
);
1354 /* read <rt > register */
1355 uint64_t rt_opd_val
= ReadRegisterUnsigned(
1356 eRegisterKindDWARF
, dwarf_zero_mips
+ rt
, 0, &success
);
1360 if (op_name
.equals_insensitive("SUBU"))
1361 result
= src_opd_val
- rt_opd_val
;
1363 result
= src_opd_val
+ rt_opd_val
;
1366 std::optional
<RegisterInfo
> reg_info_sp
=
1367 GetRegisterInfo(eRegisterKindDWARF
, dwarf_sp_mips
);
1369 context
.SetRegisterPlusOffset(*reg_info_sp
, rt_opd_val
);
1371 /* We are allocating bytes on stack */
1372 context
.type
= eContextAdjustStackPointer
;
1374 WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_sp_mips
, result
);
1377 } else if (src
== dwarf_sp_mips
) {
1378 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(2).getReg());
1380 /* read <src> register */
1381 uint64_t src_opd_val
= ReadRegisterUnsigned(
1382 eRegisterKindDWARF
, dwarf_zero_mips
+ src
, 0, &success
);
1386 /* read <rt> register */
1387 uint64_t rt_opd_val
= ReadRegisterUnsigned(
1388 eRegisterKindDWARF
, dwarf_zero_mips
+ rt
, 0, &success
);
1394 if (op_name
.equals_insensitive("SUBU"))
1395 result
= src_opd_val
- rt_opd_val
;
1397 result
= src_opd_val
+ rt_opd_val
;
1399 context
.SetImmediateSigned(result
);
1400 context
.type
= eContextImmediate
;
1402 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
,
1403 dwarf_zero_mips
+ dst
, result
))
1410 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst
&insn
) {
1411 // LUI rt, immediate
1412 // GPR[rt] <- sign_extend(immediate << 16)
1414 const uint32_t imm32
= insn
.getOperand(1).getImm() << 16;
1415 int64_t imm
= SignedBits(imm32
, 31, 0);
1419 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1420 context
.SetImmediateSigned(imm
);
1421 context
.type
= eContextImmediate
;
1423 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
,
1424 dwarf_zero_mips
+ rt
, imm
);
1427 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst
&insn
) {
1428 bool success
= false;
1429 const uint32_t imm9
= insn
.getOperand(0).getImm();
1432 // This instruction operates implicitly on stack pointer, so read <sp>
1434 uint64_t src_opd_val
=
1435 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_sp_mips
, 0, &success
);
1439 result
= src_opd_val
+ imm9
;
1442 std::optional
<RegisterInfo
> reg_info_sp
=
1443 GetRegisterInfo(eRegisterKindDWARF
, dwarf_sp_mips
);
1445 context
.SetRegisterPlusOffset(*reg_info_sp
, imm9
);
1447 // We are adjusting the stack.
1448 context
.type
= eContextAdjustStackPointer
;
1450 WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_sp_mips
, result
);
1454 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst
&insn
) {
1455 bool success
= false;
1457 const uint32_t imm4
= insn
.getOperand(2).getImm();
1460 // The source and destination register is same for this instruction.
1461 base
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1463 // We are looking for stack adjustment only
1464 if (base
== dwarf_sp_mips
) {
1465 // Read stack pointer register
1466 uint64_t src_opd_val
= ReadRegisterUnsigned(
1467 eRegisterKindDWARF
, dwarf_zero_mips
+ base
, 0, &success
);
1471 result
= src_opd_val
+ imm4
;
1474 std::optional
<RegisterInfo
> reg_info_sp
=
1475 GetRegisterInfo(eRegisterKindDWARF
, dwarf_sp_mips
);
1477 context
.SetRegisterPlusOffset(*reg_info_sp
, imm4
);
1479 // We are adjusting the stack.
1480 context
.type
= eContextAdjustStackPointer
;
1482 WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_sp_mips
, result
);
1488 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst
&insn
) {
1489 bool success
= false;
1490 uint32_t imm5
= insn
.getOperand(2).getImm();
1492 Context bad_vaddr_context
;
1495 src
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1496 base
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1498 std::optional
<RegisterInfo
> reg_info_base
=
1499 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
);
1503 // read base register
1504 address
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_zero_mips
+ base
, 0,
1509 // destination address
1510 address
= address
+ imm5
;
1512 // We use bad_vaddr_context to store base address which is used by H/W
1513 // watchpoint Set the bad_vaddr register with base address used in the
1515 bad_vaddr_context
.type
= eContextInvalid
;
1516 WriteRegisterUnsigned(bad_vaddr_context
, eRegisterKindDWARF
, dwarf_bad_mips
,
1519 // We look for sp based non-volatile register stores.
1520 if (base
== dwarf_sp_mips
&& nonvolatile_reg_p(src
)) {
1521 RegisterInfo reg_info_src
= {};
1523 context
.type
= eContextPushRegisterOnStack
;
1524 context
.SetRegisterToRegisterPlusOffset(reg_info_src
, *reg_info_base
, 0);
1526 RegisterValue::BytesContainer
buffer(reg_info_src
.byte_size
);
1529 std::optional
<RegisterValue
> data_src
= ReadRegister(*reg_info_base
);
1533 if (data_src
->GetAsMemoryData(reg_info_src
, buffer
.data(),
1534 reg_info_src
.byte_size
, eByteOrderLittle
,
1538 if (!WriteMemory(context
, address
, buffer
.data(), reg_info_src
.byte_size
))
1547 /* Emulate SWM16,SWM32 and SWP instruction.
1549 SWM16 always has stack pointer as a base register (but it is still available
1550 in MCInst as an operand).
1551 SWM32 and SWP can have base register other than stack pointer.
1553 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst
&insn
) {
1554 bool success
= false;
1556 uint32_t num_operands
= insn
.getNumOperands(); // No of operands vary based on
1557 // no of regs to store.
1559 // Base register is second last operand of the instruction.
1561 m_reg_info
->getEncodingValue(insn
.getOperand(num_operands
- 2).getReg());
1563 // We are looking for sp based stores so if base is not a stack pointer then
1565 if (base
!= dwarf_sp_mips
)
1568 // offset is always the last operand.
1569 uint32_t offset
= insn
.getOperand(num_operands
- 1).getImm();
1571 std::optional
<RegisterInfo
> reg_info_base
=
1572 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
);
1577 uint32_t base_address
= ReadRegisterUnsigned(
1578 eRegisterKindDWARF
, dwarf_zero_mips
+ base
, 0, &success
);
1582 // Resulting base addrss
1583 base_address
= base_address
+ offset
;
1585 // Total no of registers to be stored are num_operands-2.
1586 for (uint32_t i
= 0; i
< num_operands
- 2; i
++) {
1587 // Get the register number to be stored.
1588 src
= m_reg_info
->getEncodingValue(insn
.getOperand(i
).getReg());
1591 Record only non-volatile stores.
1592 This check is required for SWP instruction because source operand could
1594 SWM16 and SWM32 instruction always has saved registers as source
1597 if (!nonvolatile_reg_p(src
))
1600 std::optional
<RegisterInfo
> reg_info_src
=
1601 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ src
);
1606 context
.type
= eContextPushRegisterOnStack
;
1607 context
.SetRegisterToRegisterPlusOffset(*reg_info_src
, *reg_info_base
, 0);
1609 RegisterValue::BytesContainer
buffer(reg_info_src
->byte_size
);
1612 std::optional
<RegisterValue
> data_src
= ReadRegister(*reg_info_base
);
1616 if (data_src
->GetAsMemoryData(*reg_info_src
, buffer
.data(),
1617 reg_info_src
->byte_size
, eByteOrderLittle
,
1621 if (!WriteMemory(context
, base_address
, buffer
.data(),
1622 reg_info_src
->byte_size
))
1625 // Stack address for next register
1626 base_address
= base_address
+ reg_info_src
->byte_size
;
1631 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst
&insn
) {
1632 bool success
= false;
1633 uint32_t src
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1634 uint32_t base
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1635 uint32_t imm5
= insn
.getOperand(2).getImm();
1636 Context bad_vaddr_context
;
1638 if (!GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
))
1641 // read base register
1642 uint32_t base_address
= ReadRegisterUnsigned(
1643 eRegisterKindDWARF
, dwarf_zero_mips
+ base
, 0, &success
);
1647 base_address
= base_address
+ imm5
;
1649 // We use bad_vaddr_context to store base address which is used by H/W
1650 // watchpoint Set the bad_vaddr register with base address used in the
1652 bad_vaddr_context
.type
= eContextInvalid
;
1653 WriteRegisterUnsigned(bad_vaddr_context
, eRegisterKindDWARF
, dwarf_bad_mips
,
1656 if (base
== dwarf_sp_mips
&& nonvolatile_reg_p(src
)) {
1657 RegisterValue data_src
;
1658 std::optional
<RegisterInfo
> reg_info_src
=
1659 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ src
);
1664 context
.type
= eContextPopRegisterOffStack
;
1665 context
.SetAddress(base_address
);
1667 return WriteRegister(context
, *reg_info_src
, data_src
);
1673 /* Emulate LWM16, LWM32 and LWP instructions.
1675 LWM16 always has stack pointer as a base register (but it is still available
1676 in MCInst as an operand).
1677 LWM32 and LWP can have base register other than stack pointer.
1679 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst
&insn
) {
1680 bool success
= false;
1682 uint32_t num_operands
= insn
.getNumOperands(); // No of operands vary based on
1683 // no of regs to store.
1684 uint32_t imm
= insn
.getOperand(num_operands
- 1)
1685 .getImm(); // imm is the last operand in the instruction.
1687 // Base register is second last operand of the instruction.
1689 m_reg_info
->getEncodingValue(insn
.getOperand(num_operands
- 2).getReg());
1691 // We are looking for sp based loads so if base is not a stack pointer then
1693 if (base
!= dwarf_sp_mips
)
1696 uint32_t base_address
= ReadRegisterUnsigned(
1697 eRegisterKindDWARF
, dwarf_zero_mips
+ base
, 0, &success
);
1701 base_address
= base_address
+ imm
;
1703 RegisterValue data_dst
;
1705 // Total no of registers to be re-stored are num_operands-2.
1706 for (uint32_t i
= 0; i
< num_operands
- 2; i
++) {
1707 // Get the register number to be re-stored.
1708 dst
= m_reg_info
->getEncodingValue(insn
.getOperand(i
).getReg());
1711 Record only non-volatile loads.
1712 This check is required for LWP instruction because destination operand
1713 could be any register.
1714 LWM16 and LWM32 instruction always has saved registers as destination
1717 if (!nonvolatile_reg_p(dst
))
1720 std::optional
<RegisterInfo
> reg_info_dst
=
1721 GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ dst
);
1726 context
.type
= eContextPopRegisterOffStack
;
1727 context
.SetAddress(base_address
+ (i
* 4));
1729 if (!WriteRegister(context
, *reg_info_dst
, data_dst
))
1736 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst
&insn
) {
1737 bool success
= false;
1738 int32_t imm5
= insn
.getOperand(0).getImm();
1740 /* JRADDIUSP immediate
1742 * SP <- SP + zero_extend(Immediate << 2)
1745 // This instruction operates implicitly on stack pointer, so read <sp>
1747 int32_t src_opd_val
=
1748 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_sp_mips
, 0, &success
);
1753 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_ra_mips
, 0, &success
);
1757 int32_t result
= src_opd_val
+ imm5
;
1762 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
1766 std::optional
<RegisterInfo
> reg_info_sp
=
1767 GetRegisterInfo(eRegisterKindDWARF
, dwarf_sp_mips
);
1769 context
.SetRegisterPlusOffset(*reg_info_sp
, imm5
);
1771 // We are adjusting stack
1772 context
.type
= eContextAdjustStackPointer
;
1775 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_sp_mips
,
1779 static int IsAdd64bitOverflow(int32_t a
, int32_t b
) {
1780 int32_t r
= (uint32_t)a
+ (uint32_t)b
;
1781 return (a
< 0 && b
< 0 && r
>= 0) || (a
>= 0 && b
>= 0 && r
< 0);
1785 Emulate below MIPS branch instructions.
1786 BEQ, BNE : Branch on condition
1787 BEQL, BNEL : Branch likely
1789 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst
&insn
) {
1790 bool success
= false;
1792 int32_t offset
, pc
, target
= 0, rs_val
, rt_val
;
1793 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
1795 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1796 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1797 offset
= insn
.getOperand(2).getImm();
1799 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
1803 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1804 dwarf_zero_mips
+ rs
, 0, &success
);
1808 rt_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1809 dwarf_zero_mips
+ rt
, 0, &success
);
1813 if (op_name
.equals_insensitive("BEQ") || op_name
.equals_insensitive("BEQL")) {
1814 if (rs_val
== rt_val
)
1815 target
= pc
+ offset
;
1818 } else if (op_name
.equals_insensitive("BNE") ||
1819 op_name
.equals_insensitive("BNEL")) {
1820 if (rs_val
!= rt_val
)
1821 target
= pc
+ offset
;
1827 context
.type
= eContextRelativeBranchImmediate
;
1828 context
.SetImmediate(offset
);
1830 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
1835 Emulate below MIPS branch instructions.
1836 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1837 instructions with no delay slot
1839 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst
&insn
) {
1840 bool success
= false;
1842 int32_t offset
, pc
, target
= 0, rs_val
, rt_val
;
1843 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
1844 uint32_t current_inst_size
= m_insn_info
->get(insn
.getOpcode()).getSize();
1846 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1847 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
1848 offset
= insn
.getOperand(2).getImm();
1850 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
1854 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1855 dwarf_zero_mips
+ rs
, 0, &success
);
1859 rt_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1860 dwarf_zero_mips
+ rt
, 0, &success
);
1864 if (op_name
.equals_insensitive("BEQC")) {
1865 if (rs_val
== rt_val
)
1866 target
= pc
+ offset
;
1869 } else if (op_name
.equals_insensitive("BNEC")) {
1870 if (rs_val
!= rt_val
)
1871 target
= pc
+ offset
;
1874 } else if (op_name
.equals_insensitive("BLTC")) {
1875 if (rs_val
< rt_val
)
1876 target
= pc
+ offset
;
1879 } else if (op_name
.equals_insensitive("BGEC")) {
1880 if (rs_val
>= rt_val
)
1881 target
= pc
+ offset
;
1884 } else if (op_name
.equals_insensitive("BLTUC")) {
1885 if (rs_val
< rt_val
)
1886 target
= pc
+ offset
;
1889 } else if (op_name
.equals_insensitive("BGEUC")) {
1890 if ((uint32_t)rs_val
>= (uint32_t)rt_val
)
1891 target
= pc
+ offset
;
1894 } else if (op_name
.equals_insensitive("BOVC")) {
1895 if (IsAdd64bitOverflow(rs_val
, rt_val
))
1896 target
= pc
+ offset
;
1899 } else if (op_name
.equals_insensitive("BNVC")) {
1900 if (!IsAdd64bitOverflow(rs_val
, rt_val
))
1901 target
= pc
+ offset
;
1907 context
.type
= eContextRelativeBranchImmediate
;
1908 context
.SetImmediate(current_inst_size
+ offset
);
1910 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
1915 Emulate below MIPS conditional branch and link instructions.
1916 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1918 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst
&insn
) {
1919 bool success
= false;
1921 int32_t offset
, pc
, target
= 0;
1923 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
1925 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1926 offset
= insn
.getOperand(1).getImm();
1928 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
1932 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
1933 dwarf_zero_mips
+ rs
, 0, &success
);
1937 if (op_name
.equals_insensitive("BLEZALC")) {
1939 target
= pc
+ offset
;
1942 } else if (op_name
.equals_insensitive("BGEZALC")) {
1944 target
= pc
+ offset
;
1947 } else if (op_name
.equals_insensitive("BLTZALC")) {
1949 target
= pc
+ offset
;
1952 } else if (op_name
.equals_insensitive("BGTZALC")) {
1954 target
= pc
+ offset
;
1957 } else if (op_name
.equals_insensitive("BEQZALC")) {
1959 target
= pc
+ offset
;
1962 } else if (op_name
.equals_insensitive("BNEZALC")) {
1964 target
= pc
+ offset
;
1971 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
1975 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
1983 Emulate below MIPS Non-Compact conditional branch and link instructions.
1985 BLTZALL, BGEZALL : Branch likely
1987 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst
&insn
) {
1988 bool success
= false;
1990 int32_t offset
, pc
, target
= 0;
1992 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
1994 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
1995 offset
= insn
.getOperand(1).getImm();
1997 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2001 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2002 dwarf_zero_mips
+ rs
, 0, &success
);
2006 if (op_name
.equals_insensitive("BLTZAL") ||
2007 op_name
.equals_insensitive("BLTZALL")) {
2008 if ((int32_t)rs_val
< 0)
2009 target
= pc
+ offset
;
2012 } else if (op_name
.equals_insensitive("BGEZAL") ||
2013 op_name
.equals_insensitive("BGEZALL")) {
2014 if ((int32_t)rs_val
>= 0)
2015 target
= pc
+ offset
;
2022 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2026 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2034 Emulate below MIPS branch instructions.
2035 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2036 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2038 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst
&insn
) {
2039 bool success
= false;
2041 int32_t offset
, pc
, target
= 0;
2043 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2045 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2046 offset
= insn
.getOperand(1).getImm();
2048 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2052 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2053 dwarf_zero_mips
+ rs
, 0, &success
);
2057 if (op_name
.equals_insensitive("BLTZL") ||
2058 op_name
.equals_insensitive("BLTZ")) {
2060 target
= pc
+ offset
;
2063 } else if (op_name
.equals_insensitive("BGEZL") ||
2064 op_name
.equals_insensitive("BGEZ")) {
2066 target
= pc
+ offset
;
2069 } else if (op_name
.equals_insensitive("BGTZL") ||
2070 op_name
.equals_insensitive("BGTZ")) {
2072 target
= pc
+ offset
;
2075 } else if (op_name
.equals_insensitive("BLEZL") ||
2076 op_name
.equals_insensitive("BLEZ")) {
2078 target
= pc
+ offset
;
2084 context
.type
= eContextRelativeBranchImmediate
;
2085 context
.SetImmediate(offset
);
2087 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2092 Emulate below MIPS branch instructions.
2093 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2095 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst
&insn
) {
2096 bool success
= false;
2098 int32_t offset
, pc
, target
= 0;
2100 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2101 uint32_t current_inst_size
= m_insn_info
->get(insn
.getOpcode()).getSize();
2103 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2104 offset
= insn
.getOperand(1).getImm();
2106 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2110 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2111 dwarf_zero_mips
+ rs
, 0, &success
);
2115 if (op_name
.equals_insensitive("BLTZC")) {
2117 target
= pc
+ offset
;
2120 } else if (op_name
.equals_insensitive("BLEZC")) {
2122 target
= pc
+ offset
;
2125 } else if (op_name
.equals_insensitive("BGEZC")) {
2127 target
= pc
+ offset
;
2130 } else if (op_name
.equals_insensitive("BGTZC")) {
2132 target
= pc
+ offset
;
2135 } else if (op_name
.equals_insensitive("BEQZC")) {
2137 target
= pc
+ offset
;
2140 } else if (op_name
.equals_insensitive("BNEZC")) {
2142 target
= pc
+ offset
;
2148 context
.type
= eContextRelativeBranchImmediate
;
2149 context
.SetImmediate(current_inst_size
+ offset
);
2151 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2155 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst
&insn
) {
2156 bool success
= false;
2157 int32_t offset
, pc
, target
;
2158 uint32_t current_inst_size
= m_insn_info
->get(insn
.getOpcode()).getSize();
2160 offset
= insn
.getOperand(0).getImm();
2162 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2166 // unconditional branch
2167 target
= pc
+ offset
;
2170 context
.type
= eContextRelativeBranchImmediate
;
2171 context
.SetImmediate(current_inst_size
+ offset
);
2173 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2178 BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2179 BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2180 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2182 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst
&insn
) {
2183 bool success
= false;
2185 uint32_t current_inst_size
= m_insn_info
->get(insn
.getOpcode()).getSize();
2186 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2187 bool update_ra
= false;
2188 uint32_t ra_offset
= 0;
2192 * condition <- (GPR[rs] = 0)
2194 * PC = PC + sign_ext (offset || 0)
2197 * condition <- (GPR[rs] != 0)
2199 * PC = PC + sign_ext (offset || 0)
2201 * BEQZC rs, offset (compact instruction: No delay slot)
2202 * condition <- (GPR[rs] == 0)
2204 * PC = PC + 4 + sign_ext (offset || 0)
2207 uint32_t rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2208 int32_t offset
= insn
.getOperand(1).getImm();
2211 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2215 int32_t rs_val
= (int32_t)ReadRegisterUnsigned(
2216 eRegisterKindDWARF
, dwarf_zero_mips
+ rs
, 0, &success
);
2220 if (op_name
.equals_insensitive("BEQZ16_MM")) {
2222 target
= pc
+ offset
;
2224 target
= pc
+ current_inst_size
+
2225 m_next_inst_size
; // Skip delay slot instruction.
2226 } else if (op_name
.equals_insensitive("BNEZ16_MM")) {
2228 target
= pc
+ offset
;
2230 target
= pc
+ current_inst_size
+
2231 m_next_inst_size
; // Skip delay slot instruction.
2232 } else if (op_name
.equals_insensitive("BEQZC_MM")) {
2234 target
= pc
+ 4 + offset
;
2238 4; // 32 bit instruction and does not have delay slot instruction.
2239 } else if (op_name
.equals_insensitive("BNEZC_MM")) {
2241 target
= pc
+ 4 + offset
;
2245 4; // 32 bit instruction and does not have delay slot instruction.
2246 } else if (op_name
.equals_insensitive("BGEZALS_MM")) {
2248 target
= pc
+ offset
;
2250 target
= pc
+ 6; // 32 bit instruction with short (2-byte) delay slot
2254 } else if (op_name
.equals_insensitive("BLTZALS_MM")) {
2256 target
= pc
+ offset
;
2258 target
= pc
+ 6; // 32 bit instruction with short (2-byte) delay slot
2265 context
.type
= eContextRelativeBranchImmediate
;
2266 context
.SetImmediate(current_inst_size
+ offset
);
2268 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2273 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2280 /* Emulate micromips jump instructions.
2283 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst
&insn
) {
2284 bool success
= false;
2285 uint32_t ra_offset
= 0;
2286 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2288 uint32_t rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2291 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2295 uint32_t rs_val
= ReadRegisterUnsigned(eRegisterKindDWARF
,
2296 dwarf_zero_mips
+ rs
, 0, &success
);
2300 if (op_name
.equals_insensitive("JALR16_MM"))
2301 ra_offset
= 6; // 2-byte instruction with 4-byte delay slot.
2302 else if (op_name
.equals_insensitive("JALRS16_MM"))
2303 ra_offset
= 4; // 2-byte instruction with 2-byte delay slot.
2307 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2311 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2318 /* Emulate JALS and JALX instructions.
2319 JALS 32 bit instruction with short (2-byte) delay slot.
2320 JALX 32 bit instruction with 4-byte delay slot.
2322 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst
&insn
) {
2323 bool success
= false;
2324 uint32_t offset
= 0, target
= 0, pc
= 0, ra_offset
= 0;
2325 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2330 * offset = sign_ext (offset << 1)
2331 * PC = PC[31-27] | offset
2334 * offset = sign_ext (offset << 2)
2335 * PC = PC[31-28] | offset
2337 offset
= insn
.getOperand(0).getImm();
2339 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2343 // These are PC-region branches and not PC-relative.
2344 if (op_name
.equals_insensitive("JALS_MM")) {
2345 // target address is in the “current” 128 MB-aligned region
2346 target
= (pc
& 0xF8000000UL
) | offset
;
2348 } else if (op_name
.equals_insensitive("JALX_MM")) {
2349 // target address is in the “current” 256 MB-aligned region
2350 target
= (pc
& 0xF0000000UL
) | offset
;
2356 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2360 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2367 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst
&insn
) {
2368 bool success
= false;
2369 uint32_t rs
= 0, rt
= 0;
2370 int32_t pc
= 0, rs_val
= 0;
2378 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2379 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
2381 rs_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2382 dwarf_zero_mips
+ rs
, 0, &success
);
2386 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2392 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2396 // This is 4-byte instruction with 2-byte delay slot.
2397 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_zero_mips
+ rt
,
2404 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst
&insn
) {
2405 bool success
= false;
2406 int32_t offset
, pc
, target
;
2410 * offset = sign_ext (offset << 2)
2414 offset
= insn
.getOperand(0).getImm();
2416 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2420 target
= pc
+ offset
;
2424 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2428 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2435 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst
&insn
) {
2436 bool success
= false;
2437 int32_t offset
, pc
, target
;
2441 * offset = sign_ext (offset << 2)
2443 * PC = PC + 4 + offset
2445 offset
= insn
.getOperand(0).getImm();
2447 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2451 target
= pc
+ offset
;
2455 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2459 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2466 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst
&insn
) {
2467 bool success
= false;
2468 int32_t offset
, pc
, target
;
2472 * offset = sign_ext (offset << 2)
2473 * PC = PC + 4 + offset
2475 offset
= insn
.getOperand(0).getImm();
2477 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2481 target
= pc
+ offset
;
2485 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2489 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst
&insn
) {
2490 bool success
= false;
2491 uint32_t offset
, pc
;
2495 * offset = sign_ext (offset << 2)
2496 * PC = PC[63-28] | offset
2498 offset
= insn
.getOperand(0).getImm();
2500 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2504 /* This is a PC-region branch and not PC-relative */
2505 pc
= (pc
& 0xF0000000UL
) | offset
;
2509 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
, pc
);
2512 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst
&insn
) {
2513 bool success
= false;
2514 uint32_t offset
, target
, pc
;
2518 * offset = sign_ext (offset << 2)
2519 * PC = PC[63-28] | offset
2521 offset
= insn
.getOperand(0).getImm();
2523 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2527 /* This is a PC-region branch and not PC-relative */
2528 target
= (pc
& 0xF0000000UL
) | offset
;
2532 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2536 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2543 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst
&insn
) {
2544 bool success
= false;
2546 uint32_t pc
, rs_val
;
2553 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2554 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(1).getReg());
2556 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2560 rs_val
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_zero_mips
+ rs
, 0,
2567 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2571 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_zero_mips
+ rt
,
2578 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst
&insn
) {
2579 bool success
= false;
2581 int32_t target
, offset
, pc
, rt_val
;
2585 * offset = sign_ext (offset)
2586 * PC = GPR[rt] + offset
2589 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2590 offset
= insn
.getOperand(1).getImm();
2592 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2596 rt_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2597 dwarf_zero_mips
+ rt
, 0, &success
);
2601 target
= rt_val
+ offset
;
2605 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2609 if (!WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_ra_mips
,
2616 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst
&insn
) {
2617 bool success
= false;
2619 int32_t target
, offset
, rt_val
;
2623 * offset = sign_ext (offset)
2624 * PC = GPR[rt] + offset
2626 rt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2627 offset
= insn
.getOperand(1).getImm();
2629 rt_val
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2630 dwarf_zero_mips
+ rt
, 0, &success
);
2634 target
= rt_val
+ offset
;
2638 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2642 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst
&insn
) {
2643 bool success
= false;
2651 rs
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2653 rs_val
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_zero_mips
+ rs
, 0,
2660 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2665 Emulate Branch on FP True/False
2666 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2667 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2669 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst
&insn
) {
2670 bool success
= false;
2672 int32_t pc
, offset
, target
= 0;
2673 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2675 cc
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2676 offset
= insn
.getOperand(1).getImm();
2678 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2682 fcsr
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_fcsr_mips
, 0, &success
);
2686 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2687 fcsr
= ((fcsr
>> 24) & 0xfe) | ((fcsr
>> 23) & 0x01);
2689 if (op_name
.equals_insensitive("BC1F") ||
2690 op_name
.equals_insensitive("BC1FL")) {
2691 if ((fcsr
& (1 << cc
)) == 0)
2692 target
= pc
+ offset
;
2695 } else if (op_name
.equals_insensitive("BC1T") ||
2696 op_name
.equals_insensitive("BC1TL")) {
2697 if ((fcsr
& (1 << cc
)) != 0)
2698 target
= pc
+ offset
;
2704 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2708 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst
&insn
) {
2709 bool success
= false;
2712 int32_t target
, pc
, offset
;
2716 * condition <- (FPR[ft].bit0 == 0)
2718 * offset = sign_ext (offset)
2719 * PC = PC + 4 + offset
2721 ft
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2722 offset
= insn
.getOperand(1).getImm();
2724 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2728 ft_val
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_zero_mips
+ ft
, 0,
2733 if ((ft_val
& 1) == 0)
2734 target
= pc
+ 4 + offset
;
2740 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2744 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst
&insn
) {
2745 bool success
= false;
2748 int32_t target
, pc
, offset
;
2752 * condition <- (FPR[ft].bit0 != 0)
2754 * offset = sign_ext (offset)
2755 * PC = PC + 4 + offset
2757 ft
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2758 offset
= insn
.getOperand(1).getImm();
2760 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2764 ft_val
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_zero_mips
+ ft
, 0,
2769 if ((ft_val
& 1) != 0)
2770 target
= pc
+ 4 + offset
;
2776 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2781 Emulate MIPS-3D Branch instructions
2782 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2784 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2787 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst
&insn
) {
2788 bool success
= false;
2790 int32_t pc
, offset
, target
= 0;
2791 llvm::StringRef op_name
= m_insn_info
->getName(insn
.getOpcode());
2793 cc
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2794 offset
= insn
.getOperand(1).getImm();
2796 pc
= ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2800 fcsr
= (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_fcsr_mips
, 0,
2805 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2806 fcsr
= ((fcsr
>> 24) & 0xfe) | ((fcsr
>> 23) & 0x01);
2808 if (op_name
.equals_insensitive("BC1ANY2F")) {
2809 /* if any one bit is 0 */
2810 if (((fcsr
>> cc
) & 3) != 3)
2811 target
= pc
+ offset
;
2814 } else if (op_name
.equals_insensitive("BC1ANY2T")) {
2815 /* if any one bit is 1 */
2816 if (((fcsr
>> cc
) & 3) != 0)
2817 target
= pc
+ offset
;
2820 } else if (op_name
.equals_insensitive("BC1ANY4F")) {
2821 /* if any one bit is 0 */
2822 if (((fcsr
>> cc
) & 0xf) != 0xf)
2823 target
= pc
+ offset
;
2826 } else if (op_name
.equals_insensitive("BC1ANY4T")) {
2827 /* if any one bit is 1 */
2828 if (((fcsr
>> cc
) & 0xf) != 0)
2829 target
= pc
+ offset
;
2835 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2839 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst
&insn
) {
2840 return Emulate_MSA_Branch_DF(insn
, 1, true);
2843 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst
&insn
) {
2844 return Emulate_MSA_Branch_DF(insn
, 2, true);
2847 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst
&insn
) {
2848 return Emulate_MSA_Branch_DF(insn
, 4, true);
2851 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst
&insn
) {
2852 return Emulate_MSA_Branch_DF(insn
, 8, true);
2855 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst
&insn
) {
2856 return Emulate_MSA_Branch_DF(insn
, 1, false);
2859 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst
&insn
) {
2860 return Emulate_MSA_Branch_DF(insn
, 2, false);
2863 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst
&insn
) {
2864 return Emulate_MSA_Branch_DF(insn
, 4, false);
2867 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst
&insn
) {
2868 return Emulate_MSA_Branch_DF(insn
, 8, false);
2871 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst
&insn
,
2872 int element_byte_size
,
2874 bool success
= false, branch_hit
= true;
2876 RegisterValue reg_value
;
2877 const uint8_t *ptr
= nullptr;
2879 uint32_t wt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2880 int32_t offset
= insn
.getOperand(1).getImm();
2883 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2887 if (ReadRegister(eRegisterKindDWARF
, dwarf_w0_mips
+ wt
, reg_value
))
2888 ptr
= (const uint8_t *)reg_value
.GetBytes();
2892 for (int i
= 0; i
< 16 / element_byte_size
; i
++) {
2893 switch (element_byte_size
) {
2895 if ((*ptr
== 0 && bnz
) || (*ptr
!= 0 && !bnz
))
2899 if ((*(const uint16_t *)ptr
== 0 && bnz
) ||
2900 (*(const uint16_t *)ptr
!= 0 && !bnz
))
2904 if ((*(const uint32_t *)ptr
== 0 && bnz
) ||
2905 (*(const uint32_t *)ptr
!= 0 && !bnz
))
2909 if ((*(const uint64_t *)ptr
== 0 && bnz
) ||
2910 (*(const uint64_t *)ptr
!= 0 && !bnz
))
2916 ptr
= ptr
+ element_byte_size
;
2920 target
= pc
+ offset
;
2925 context
.type
= eContextRelativeBranchImmediate
;
2927 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2931 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst
&insn
) {
2932 return Emulate_MSA_Branch_V(insn
, true);
2935 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst
&insn
) {
2936 return Emulate_MSA_Branch_V(insn
, false);
2939 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst
&insn
,
2941 bool success
= false;
2943 llvm::APInt wr_val
= llvm::APInt::getZero(128);
2944 llvm::APInt fail_value
= llvm::APInt::getMaxValue(128);
2945 llvm::APInt zero_value
= llvm::APInt::getZero(128);
2946 RegisterValue reg_value
;
2948 uint32_t wt
= m_reg_info
->getEncodingValue(insn
.getOperand(0).getReg());
2949 int32_t offset
= insn
.getOperand(1).getImm();
2952 ReadRegisterUnsigned(eRegisterKindDWARF
, dwarf_pc_mips
, 0, &success
);
2956 if (ReadRegister(eRegisterKindDWARF
, dwarf_w0_mips
+ wt
, reg_value
))
2957 wr_val
= reg_value
.GetAsUInt128(fail_value
);
2961 if ((llvm::APInt::isSameValue(zero_value
, wr_val
) && !bnz
) ||
2962 (!llvm::APInt::isSameValue(zero_value
, wr_val
) && bnz
))
2963 target
= pc
+ offset
;
2968 context
.type
= eContextRelativeBranchImmediate
;
2970 return WriteRegisterUnsigned(context
, eRegisterKindDWARF
, dwarf_pc_mips
,
2974 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst
&insn
) {
2975 bool success
= false;
2977 int32_t imm
, address
;
2978 Context bad_vaddr_context
;
2980 uint32_t num_operands
= insn
.getNumOperands();
2982 m_reg_info
->getEncodingValue(insn
.getOperand(num_operands
- 2).getReg());
2983 imm
= insn
.getOperand(num_operands
- 1).getImm();
2985 if (!GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
))
2988 /* read base register */
2989 address
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
2990 dwarf_zero_mips
+ base
, 0, &success
);
2994 /* destination address */
2995 address
= address
+ imm
;
2997 /* Set the bad_vaddr register with base address used in the instruction */
2998 bad_vaddr_context
.type
= eContextInvalid
;
2999 WriteRegisterUnsigned(bad_vaddr_context
, eRegisterKindDWARF
, dwarf_bad_mips
,
3005 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst
&insn
) {
3006 bool success
= false;
3007 uint32_t base
, index
;
3008 int32_t address
, index_address
;
3009 Context bad_vaddr_context
;
3011 uint32_t num_operands
= insn
.getNumOperands();
3013 m_reg_info
->getEncodingValue(insn
.getOperand(num_operands
- 2).getReg());
3015 m_reg_info
->getEncodingValue(insn
.getOperand(num_operands
- 1).getReg());
3017 if (!GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ base
))
3020 if (!GetRegisterInfo(eRegisterKindDWARF
, dwarf_zero_mips
+ index
))
3023 /* read base register */
3024 address
= (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF
,
3025 dwarf_zero_mips
+ base
, 0, &success
);
3029 /* read index register */
3030 index_address
= (int32_t)ReadRegisterUnsigned(
3031 eRegisterKindDWARF
, dwarf_zero_mips
+ index
, 0, &success
);
3035 /* destination address */
3036 address
= address
+ index_address
;
3038 /* Set the bad_vaddr register with base address used in the instruction */
3039 bad_vaddr_context
.type
= eContextInvalid
;
3040 WriteRegisterUnsigned(bad_vaddr_context
, eRegisterKindDWARF
, dwarf_bad_mips
,