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"
46#define UInt(x) ((uint64_t)x)
47#define integer int64_t
55void LLVMInitializeMipsTargetInfo();
56void LLVMInitializeMipsTarget();
57void LLVMInitializeMipsAsmPrinter();
58void LLVMInitializeMipsTargetMC();
59void LLVMInitializeMipsDisassembler();
69 const llvm::Target *target =
70 llvm::TargetRegistry::lookupTarget(triple.getTriple(),
Status);
82 LLVMInitializeMipsTargetInfo();
83 LLVMInitializeMipsTarget();
84 LLVMInitializeMipsAsmPrinter();
85 LLVMInitializeMipsTargetMC();
86 LLVMInitializeMipsDisassembler();
87 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(),
Status);
141 std::string features;
142 uint32_t arch_flags = arch.
GetFlags();
148 features +=
"+dspr2,";
150 m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
156 llvm::MCTargetOptions MCOptions;
158 target->createMCAsmInfo(*
m_reg_info, triple.getTriple(), MCOptions));
160 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
163 m_context = std::make_unique<llvm::MCContext>(
172 features +=
"+mips16,";
174 features +=
"+micromips,";
177 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
198 return "Emulate instructions for the MIPS32 architecture.";
206 if (arch.
GetTriple().getArch() == llvm::Triple::mips ||
207 arch.
GetTriple().getArch() == llvm::Triple::mipsel) {
216 return arch.
GetTriple().getArch() == llvm::Triple::mips ||
217 arch.
GetTriple().getArch() == llvm::Triple::mipsel;
221 bool alternate_name) {
222 if (alternate_name) {
589std::optional<RegisterInfo>
677 "ADDIU rt, rs, immediate"},
688 "ADDIUS5 rd,immediate"},
691 "SWM16 reglist,offset(sp)"},
693 "SWM32 reglist,offset(base)"},
695 "SWP rs1,offset(base)"},
698 "LWM16 reglist,offset(sp)"},
700 "LWM32 reglist,offset(base)"},
702 "LWP rd,offset(base)"},
704 "JRADDIUSP immediate"},
715 "LB rt, offset(base)"},
717 "LBE rt, offset(base)"},
719 "LBU rt, offset(base)"},
721 "LBUE rt, offset(base)"},
723 "LDC1 ft, offset(base)"},
725 "LD rt, offset(base)"},
727 "LDL rt, offset(base)"},
729 "LDR rt, offset(base)"},
731 "LLD rt, offset(base)"},
733 "LDC2 rt, offset(base)"},
735 "LDXC1 fd, index (base)"},
737 "LH rt, offset(base)"},
739 "LHE rt, offset(base)"},
741 "LHU rt, offset(base)"},
743 "LHUE rt, offset(base)"},
745 "LL rt, offset(base)"},
747 "LLE rt, offset(base)"},
749 "LUXC1 fd, index (base)"},
751 "LW rt, offset(base)"},
753 "LWC1 ft, offset(base)"},
755 "LWC2 rt, offset(base)"},
757 "LWE rt, offset(base)"},
759 "LWL rt, offset(base)"},
761 "LWLE rt, offset(base)"},
763 "LWR rt, offset(base)"},
765 "LWRE rt, offset(base)"},
767 "LWXC1 fd, index (base)"},
769 "LLX rt, offset(base)"},
771 "LLXE rt, offset(base)"},
773 "LLDX rt, offset(base)"},
776 "SB rt, offset(base)"},
778 "SBE rt, offset(base)"},
780 "SC rt, offset(base)"},
782 "SCE rt, offset(base)"},
784 "SCD rt, offset(base)"},
786 "SD rt, offset(base)"},
788 "SDL rt, offset(base)"},
790 "SDR rt, offset(base)"},
792 "SDC1 ft, offset(base)"},
794 "SDC2 rt, offset(base)"},
796 "SDXC1 fs, index(base)"},
798 "SH rt, offset(base)"},
800 "SHE rt, offset(base)"},
802 "SUXC1 fs, index (base)"},
804 "SWC1 ft, offset(base)"},
806 "SWC2 rt, offset(base)"},
808 "SWE rt, offset(base)"},
810 "SWL rt, offset(base)"},
812 "SWLE rt, offset(base)"},
814 "SWR rt, offset(base)"},
816 "SWRE rt, offset(base)"},
818 "SWXC1 fs, index (base)"},
820 "SCX rt, offset(base)"},
822 "SCXE rt, offset(base)"},
824 "SCDX rt, offset(base)"},
828 "LBU16 rt, decoded_offset(base)"},
830 "LHU16 rt, left_shifted_offset(base)"},
832 "LW16 rt, left_shifted_offset(base)"},
834 "LWGP rt, left_shifted_offset(gp)"},
836 "SH16 rt, left_shifted_offset(base)"},
838 "SW16 rt, left_shifted_offset(base)"},
840 "SWSP rt, left_shifted_offset(base)"},
842 "SB16 rt, offset(base)"},
850 "BGEZALL rt,offset"},
858 "BLEZALC rs,offset"},
860 "BGEZALC rs,offset"},
862 "BLTZALC rs,offset"},
864 "BGTZALC rs,offset"},
866 "BEQZALC rs,offset"},
868 "BNEZALC rs,offset"},
870 "BEQC rs,rt,offset"},
872 "BNEC rs,rt,offset"},
874 "BLTC rs,rt,offset"},
876 "BGEC rs,rt,offset"},
878 "BLTUC rs,rt,offset"},
880 "BGEUC rs,rt,offset"},
896 "BLTZALL rt,offset"},
899 "BOVC rs,rt,offset"},
901 "BNVC rs,rt,offset"},
918 "BC1ANY2F cc, offset"},
920 "BC1ANY2T cc, offset"},
922 "BC1ANY4F cc, offset"},
924 "BC1ANY4T cc, offset"},
939 "BEQZ16 rs, offset"},
941 "BNEZ16 rs, offset"},
947 "BGEZALS rs, offset"},
949 "BLTZALS rs, offset"},
960 if (name.equals_insensitive(opcode.op_name))
968 uint64_t inst_addr) {
969 uint64_t next_inst_size = 0;
970 llvm::MCInst mc_insn;
971 llvm::MCDisassembler::DecodeStatus decode_status;
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();
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 =
1010 buf,
sizeof(uint32_t),
error,
1014 if (bytes_read == 0)
1035 bool success =
false;
1052 bool success =
false;
1053 llvm::MCInst mc_insn;
1060 llvm::MCDisassembler::DecodeStatus decode_status;
1063 decode_status =
m_alt_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1066 decode_status =
m_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1069 if (decode_status != llvm::MCDisassembler::Success)
1077 const char *op_name =
m_insn_info->getName(mc_insn.getOpcode()).data();
1079 if (op_name ==
nullptr)
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) {
1103 success = (this->*opcode_data->
callback)(mc_insn);
1107 if (auto_advance_pc) {
1114 if (old_pc == new_pc) {
1128 unwind_plan.
Clear();
1132 const bool can_replace =
false;
1135 row->GetCFAValue().SetIsRegisterPlusOffset(
dwarf_sp_mips, 0);
1178 bool success =
false;
1179 const uint32_t imm16 = insn.getOperand(2).getImm();
1182 dst =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1183 src =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1200 uint64_t result = src_opd_val + imm;
1201 std::optional<RegisterInfo> reg_info_sp =
1226 bool success =
false;
1227 uint32_t imm16 = insn.getOperand(2).getImm();
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 =
1248 address = address + imm;
1257 std::optional<RegisterInfo> reg_info_src =
1269 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1273 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1278 if (!
WriteMemory(context, address, buffer.data(), reg_info_src->byte_size))
1288 bool success =
false;
1290 int32_t imm, address;
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();
1307 address = address + imm;
1316 std::optional<RegisterInfo> reg_info_src =
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());
1346 rt =
m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
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 =
1378 rt =
m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1394 if (op_name.equals_insensitive(
"SUBU"))
1395 result = src_opd_val - rt_opd_val;
1397 result = src_opd_val + rt_opd_val;
1414 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1419 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1428 bool success =
false;
1429 const uint32_t imm9 = insn.getOperand(0).getImm();
1434 uint64_t src_opd_val =
1439 result = src_opd_val + imm9;
1442 std::optional<RegisterInfo> reg_info_sp =
1455 bool success =
false;
1457 const uint32_t imm4 = insn.getOperand(2).getImm();
1461 base =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1471 result = src_opd_val + imm4;
1474 std::optional<RegisterInfo> reg_info_sp =
1489 bool success =
false;
1490 uint32_t imm5 = insn.getOperand(2).getImm();
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 =
1510 address = address + imm5;
1529 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1533 if (data_src->GetAsMemoryData(reg_info_src, buffer.
data(),
1554 bool success =
false;
1556 uint32_t num_operands = insn.getNumOperands();
1561 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1569 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1571 std::optional<RegisterInfo> reg_info_base =
1583 base_address = base_address + offset;
1586 for (uint32_t i = 0; i < num_operands - 2; i++) {
1588 src =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1600 std::optional<RegisterInfo> reg_info_src =
1612 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1616 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1621 if (!
WriteMemory(context, base_address, buffer.data(),
1622 reg_info_src->byte_size))
1626 base_address = base_address + reg_info_src->byte_size;
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();
1647 base_address = base_address + imm5;
1658 std::optional<RegisterInfo> reg_info_src =
1680 bool success =
false;
1682 uint32_t num_operands = insn.getNumOperands();
1684 uint32_t imm = insn.getOperand(num_operands - 1)
1689 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1701 base_address = base_address + imm;
1706 for (uint32_t i = 0; i < num_operands - 2; i++) {
1708 dst =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1720 std::optional<RegisterInfo> reg_info_dst =
1737 bool success =
false;
1738 int32_t imm5 = insn.getOperand(0).getImm();
1747 int32_t src_opd_val =
1757 int32_t result = src_opd_val + imm5;
1766 std::optional<RegisterInfo> reg_info_sp =
1780 int32_t r = (uint32_t)a + (uint32_t)b;
1781 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
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();
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;
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();
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")) {
1896 target =
pc + offset;
1899 }
else if (op_name.equals_insensitive(
"BNVC")) {
1901 target =
pc + offset;
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();
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;
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();
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;
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();
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;
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();
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;
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();
2167 target =
pc + offset;
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;
2207 uint32_t rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2208 int32_t offset = insn.getOperand(1).getImm();
2220 if (op_name.equals_insensitive(
"BEQZ16_MM")) {
2222 target =
pc + offset;
2224 target =
pc + current_inst_size +
2226 }
else if (op_name.equals_insensitive(
"BNEZ16_MM")) {
2228 target =
pc + offset;
2230 target =
pc + current_inst_size +
2232 }
else if (op_name.equals_insensitive(
"BEQZC_MM")) {
2234 target =
pc + 4 + offset;
2239 }
else if (op_name.equals_insensitive(
"BNEZC_MM")) {
2241 target =
pc + 4 + offset;
2246 }
else if (op_name.equals_insensitive(
"BGEZALS_MM")) {
2248 target =
pc + offset;
2254 }
else if (op_name.equals_insensitive(
"BLTZALS_MM")) {
2256 target =
pc + offset;
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());
2300 if (op_name.equals_insensitive(
"JALR16_MM"))
2302 else if (op_name.equals_insensitive(
"JALRS16_MM"))
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());
2337 offset = insn.getOperand(0).getImm();
2344 if (op_name.equals_insensitive(
"JALS_MM")) {
2346 target = (
pc & 0xF8000000UL) | offset;
2348 }
else if (op_name.equals_insensitive(
"JALX_MM")) {
2350 target = (
pc & 0xF0000000UL) | offset;
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());
2405 bool success =
false;
2406 int32_t offset,
pc, target;
2414 offset = insn.getOperand(0).getImm();
2420 target =
pc + offset;
2436 bool success =
false;
2437 int32_t offset,
pc, target;
2445 offset = insn.getOperand(0).getImm();
2451 target =
pc + offset;
2467 bool success =
false;
2468 int32_t offset,
pc, target;
2475 offset = insn.getOperand(0).getImm();
2481 target =
pc + offset;
2490 bool success =
false;
2491 uint32_t offset,
pc;
2498 offset = insn.getOperand(0).getImm();
2505 pc = (
pc & 0xF0000000UL) | offset;
2513 bool success =
false;
2514 uint32_t offset, target,
pc;
2521 offset = insn.getOperand(0).getImm();
2528 target = (
pc & 0xF0000000UL) | offset;
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());
2579 bool success =
false;
2581 int32_t target, offset,
pc, rt_val;
2589 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2590 offset = insn.getOperand(1).getImm();
2601 target = rt_val + offset;
2617 bool success =
false;
2619 int32_t target, offset, rt_val;
2626 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2627 offset = insn.getOperand(1).getImm();
2634 target = rt_val + offset;
2643 bool success =
false;
2651 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
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();
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;
2709 bool success =
false;
2712 int32_t target,
pc, offset;
2721 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2722 offset = insn.getOperand(1).getImm();
2733 if ((ft_val & 1) == 0)
2734 target =
pc + 4 + offset;
2745 bool success =
false;
2748 int32_t target,
pc, offset;
2757 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2758 offset = insn.getOperand(1).getImm();
2769 if ((ft_val & 1) != 0)
2770 target =
pc + 4 + offset;
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();
2806 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2808 if (op_name.equals_insensitive(
"BC1ANY2F")) {
2810 if (((fcsr >> cc) & 3) != 3)
2811 target =
pc + offset;
2814 }
else if (op_name.equals_insensitive(
"BC1ANY2T")) {
2816 if (((fcsr >> cc) & 3) != 0)
2817 target =
pc + offset;
2820 }
else if (op_name.equals_insensitive(
"BC1ANY4F")) {
2822 if (((fcsr >> cc) & 0xf) != 0xf)
2823 target =
pc + offset;
2826 }
else if (op_name.equals_insensitive(
"BC1ANY4T")) {
2828 if (((fcsr >> cc) & 0xf) != 0)
2829 target =
pc + offset;
2872 int element_byte_size,
2874 bool success =
false, branch_hit =
true;
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();
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;
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);
2948 uint32_t wt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2949 int32_t offset = insn.getOperand(1).getImm();
2961 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2962 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2963 target =
pc + offset;
2975 bool success =
false;
2977 int32_t imm, address;
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();
2995 address = address + imm;
3006 bool success =
false;
3007 uint32_t base, index;
3008 int32_t address, index_address;
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());
3036 address = address + index_address;
static llvm::raw_ostream & error(Stream &strm)
static int IsAdd64bitOverflow(int32_t a, int32_t b)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, lldb_private::InstructionType inst_type)
bool Emulate_J(llvm::MCInst &insn)
bool Emulate_ADDiu(llvm::MCInst &insn)
bool Emulate_SUBU_ADDU(llvm::MCInst &insn)
bool Emulate_BXX_3ops(llvm::MCInst &insn)
bool Emulate_BNZH(llvm::MCInst &insn)
bool Emulate_BZV(llvm::MCInst &insn)
const char * GetRegisterName(unsigned reg_num, bool alternate_name)
bool Emulate_BNZW(llvm::MCInst &insn)
static bool SupportsEmulatingInstructionsOfTypeStatic(lldb_private::InstructionType inst_type)
bool Emulate_LWSP(llvm::MCInst &insn)
bool Emulate_BZD(llvm::MCInst &insn)
EmulateInstructionMIPS(const lldb_private::ArchSpec &arch)
bool Emulate_BZB(llvm::MCInst &insn)
bool EvaluateInstruction(uint32_t evaluate_options) override
bool SetInstruction(const lldb_private::Opcode &insn_opcode, const lldb_private::Address &inst_addr, lldb_private::Target *target) override
bool Emulate_B16_MM(llvm::MCInst &insn)
bool Emulate_SWM16_32(llvm::MCInst &insn)
uint32_t m_next_inst_size
bool Emulate_Branch_MM(llvm::MCInst &insn)
bool Emulate_BC1EQZ(llvm::MCInst &insn)
uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data, uint64_t inst_addr)
bool Emulate_SW(llvm::MCInst &insn)
static llvm::StringRef GetPluginDescriptionStatic()
std::unique_ptr< llvm::MCDisassembler > m_alt_disasm
bool Emulate_LWM16_32(llvm::MCInst &insn)
bool Emulate_JAL(llvm::MCInst &insn)
bool Emulate_JR(llvm::MCInst &insn)
bool Emulate_JRADDIUSP(llvm::MCInst &insn)
std::optional< lldb_private::RegisterInfo > GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override
bool Emulate_BC(llvm::MCInst &insn)
bool Emulate_Bcond_Link(llvm::MCInst &insn)
bool Emulate_JALx(llvm::MCInst &insn)
bool Emulate_LDST_Reg(llvm::MCInst &insn)
static MipsOpcode * GetOpcodeForInstruction(llvm::StringRef name)
bool Emulate_JALR(llvm::MCInst &insn)
bool Emulate_BZW(llvm::MCInst &insn)
bool Emulate_JIALC(llvm::MCInst &insn)
std::unique_ptr< llvm::MCContext > m_context
bool Emulate_Bcond_Link_C(llvm::MCInst &insn)
static llvm::StringRef GetPluginNameStatic()
std::unique_ptr< llvm::MCDisassembler > m_disasm
bool Emulate_3D_branch(llvm::MCInst &insn)
bool Emulate_BNZB(llvm::MCInst &insn)
bool Emulate_BNZD(llvm::MCInst &insn)
bool ReadInstruction() override
bool Emulate_JALRx16_MM(llvm::MCInst &insn)
bool Emulate_BALC(llvm::MCInst &insn)
bool Emulate_BNZV(llvm::MCInst &insn)
bool Emulate_BXX_3ops_C(llvm::MCInst &insn)
bool nonvolatile_reg_p(uint32_t regnum)
bool Emulate_JIC(llvm::MCInst &insn)
bool SetTargetTriple(const lldb_private::ArchSpec &arch) override
bool Emulate_LW(llvm::MCInst &insn)
bool Emulate_BAL(llvm::MCInst &insn)
bool Emulate_SWSP(llvm::MCInst &insn)
std::unique_ptr< llvm::MCSubtargetInfo > m_subtype_info
bool Emulate_JALRS(llvm::MCInst &insn)
bool Emulate_ADDIUSP(llvm::MCInst &insn)
bool Emulate_BXX_2ops_C(llvm::MCInst &insn)
bool Emulate_FP_branch(llvm::MCInst &insn)
bool Emulate_BXX_2ops(llvm::MCInst &insn)
bool Emulate_LUI(llvm::MCInst &insn)
std::unique_ptr< llvm::MCAsmInfo > m_asm_info
bool Emulate_BZH(llvm::MCInst &insn)
bool Emulate_BC1NEZ(llvm::MCInst &insn)
bool CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override
bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size, bool bnz)
bool Emulate_LDST_Imm(llvm::MCInst &insn)
std::unique_ptr< llvm::MCInstrInfo > m_insn_info
bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz)
bool Emulate_ADDIUS5(llvm::MCInst &insn)
std::unique_ptr< llvm::MCSubtargetInfo > m_alt_subtype_info
std::unique_ptr< llvm::MCRegisterInfo > m_reg_info
A section + offset based address class.
AddressClass GetAddressClass() const
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
uint32_t GetFlags() const
"lldb/Core/EmulateInstruction.h" A class that allows emulation of CPU opcodes.
@ eContextRelativeBranchImmediate
@ eContextAdjustStackPointer
@ eContextPushRegisterOnStack
@ eContextPopRegisterOffStack
lldb::ByteOrder GetByteOrder() const
std::optional< RegisterValue > ReadRegister(const RegisterInfo ®_info)
bool WriteRegister(const Context &context, const RegisterInfo &ref_info, const RegisterValue ®_value)
bool WriteRegisterUnsigned(const Context &context, const RegisterInfo ®_info, uint64_t reg_value)
bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src, size_t src_len)
uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
uint32_t GetAddressByteSize() const
virtual bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, Target *target)
uint64_t ReadRegisterUnsigned(const RegisterInfo ®_info, uint64_t fail_value, bool *success_ptr)
uint32_t GetByteSize() const
uint32_t GetData(DataExtractor &data) const
void SetOpcode32(uint32_t inst, lldb::ByteOrder order)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
llvm::APInt GetAsUInt128(const llvm::APInt &fail_value, bool *success_ptr=nullptr) const
const void * GetBytes() const
llvm::SmallVector< uint8_t, kTypicalRegisterByteSize > BytesContainer
virtual size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory=false, lldb::addr_t *load_addr_ptr=nullptr)
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
void SetRegisterKind(lldb::RegisterKind kind)
void SetReturnAddressRegister(uint32_t regnum)
void AppendRow(const RowSP &row_sp)
std::shared_ptr< Row > RowSP
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
A class that represents a running process on the host machine.
InstructionType
Instruction types.
static int64_t SignedBits(const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindDWARF
the register numbers seen DWARF
bool(EmulateInstructionMIPS::* callback)(llvm::MCInst &insn)
void SetImmediate(uint64_t immediate)
void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset)
void SetImmediateSigned(int64_t signed_immediate)
void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset)
void SetAddress(lldb::addr_t address)
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
const char * alt_name
Alternate name of this register, can be NULL.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
llvm::ArrayRef< uint8_t > data(const uint8_t *context_base) const
const char * name
Name of this register, can't be NULL.
lldb::Format format
Default display format.