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,
Status);
82 LLVMInitializeMipsTargetInfo();
83 LLVMInitializeMipsTarget();
84 LLVMInitializeMipsAsmPrinter();
85 LLVMInitializeMipsTargetMC();
86 LLVMInitializeMipsDisassembler();
87 target = llvm::TargetRegistry::lookupTarget(triple,
Status);
141 std::string features;
142 uint32_t arch_flags = arch.
GetFlags();
148 features +=
"+dspr2,";
150 m_reg_info.reset(target->createMCRegInfo(triple));
156 llvm::MCTargetOptions MCOptions;
158 m_subtype_info.reset(target->createMCSubtargetInfo(triple, cpu, features));
161 m_context = std::make_unique<llvm::MCContext>(
170 features +=
"+mips16,";
172 features +=
"+micromips,";
175 target->createMCSubtargetInfo(triple, cpu, features));
196 return "Emulate instructions for the MIPS32 architecture.";
204 if (arch.
GetTriple().getArch() == llvm::Triple::mips ||
205 arch.
GetTriple().getArch() == llvm::Triple::mipsel) {
214 return arch.
GetTriple().getArch() == llvm::Triple::mips ||
215 arch.
GetTriple().getArch() == llvm::Triple::mipsel;
219 bool alternate_name) {
220 if (alternate_name) {
587std::optional<RegisterInfo>
675 "ADDIU rt, rs, immediate"},
686 "ADDIUS5 rd,immediate"},
689 "SWM16 reglist,offset(sp)"},
691 "SWM32 reglist,offset(base)"},
693 "SWP rs1,offset(base)"},
696 "LWM16 reglist,offset(sp)"},
698 "LWM32 reglist,offset(base)"},
700 "LWP rd,offset(base)"},
702 "JRADDIUSP immediate"},
713 "LB rt, offset(base)"},
715 "LBE rt, offset(base)"},
717 "LBU rt, offset(base)"},
719 "LBUE rt, offset(base)"},
721 "LDC1 ft, offset(base)"},
723 "LD rt, offset(base)"},
725 "LDL rt, offset(base)"},
727 "LDR rt, offset(base)"},
729 "LLD rt, offset(base)"},
731 "LDC2 rt, offset(base)"},
733 "LDXC1 fd, index (base)"},
735 "LH rt, offset(base)"},
737 "LHE rt, offset(base)"},
739 "LHU rt, offset(base)"},
741 "LHUE rt, offset(base)"},
743 "LL rt, offset(base)"},
745 "LLE rt, offset(base)"},
747 "LUXC1 fd, index (base)"},
749 "LW rt, offset(base)"},
751 "LWC1 ft, offset(base)"},
753 "LWC2 rt, offset(base)"},
755 "LWE rt, offset(base)"},
757 "LWL rt, offset(base)"},
759 "LWLE rt, offset(base)"},
761 "LWR rt, offset(base)"},
763 "LWRE rt, offset(base)"},
765 "LWXC1 fd, index (base)"},
767 "LLX rt, offset(base)"},
769 "LLXE rt, offset(base)"},
771 "LLDX rt, offset(base)"},
774 "SB rt, offset(base)"},
776 "SBE rt, offset(base)"},
778 "SC rt, offset(base)"},
780 "SCE rt, offset(base)"},
782 "SCD rt, offset(base)"},
784 "SD rt, offset(base)"},
786 "SDL rt, offset(base)"},
788 "SDR rt, offset(base)"},
790 "SDC1 ft, offset(base)"},
792 "SDC2 rt, offset(base)"},
794 "SDXC1 fs, index(base)"},
796 "SH rt, offset(base)"},
798 "SHE rt, offset(base)"},
800 "SUXC1 fs, index (base)"},
802 "SWC1 ft, offset(base)"},
804 "SWC2 rt, offset(base)"},
806 "SWE rt, offset(base)"},
808 "SWL rt, offset(base)"},
810 "SWLE rt, offset(base)"},
812 "SWR rt, offset(base)"},
814 "SWRE rt, offset(base)"},
816 "SWXC1 fs, index (base)"},
818 "SCX rt, offset(base)"},
820 "SCXE rt, offset(base)"},
822 "SCDX rt, offset(base)"},
826 "LBU16 rt, decoded_offset(base)"},
828 "LHU16 rt, left_shifted_offset(base)"},
830 "LW16 rt, left_shifted_offset(base)"},
832 "LWGP rt, left_shifted_offset(gp)"},
834 "SH16 rt, left_shifted_offset(base)"},
836 "SW16 rt, left_shifted_offset(base)"},
838 "SWSP rt, left_shifted_offset(base)"},
840 "SB16 rt, offset(base)"},
848 "BGEZALL rt,offset"},
856 "BLEZALC rs,offset"},
858 "BGEZALC rs,offset"},
860 "BLTZALC rs,offset"},
862 "BGTZALC rs,offset"},
864 "BEQZALC rs,offset"},
866 "BNEZALC rs,offset"},
868 "BEQC rs,rt,offset"},
870 "BNEC rs,rt,offset"},
872 "BLTC rs,rt,offset"},
874 "BGEC rs,rt,offset"},
876 "BLTUC rs,rt,offset"},
878 "BGEUC rs,rt,offset"},
894 "BLTZALL rt,offset"},
897 "BOVC rs,rt,offset"},
899 "BNVC rs,rt,offset"},
916 "BC1ANY2F cc, offset"},
918 "BC1ANY2T cc, offset"},
920 "BC1ANY4F cc, offset"},
922 "BC1ANY4T cc, offset"},
937 "BEQZ16 rs, offset"},
939 "BNEZ16 rs, offset"},
945 "BGEZALS rs, offset"},
947 "BLTZALS rs, offset"},
958 if (name.equals_insensitive(opcode.op_name))
966 uint64_t inst_addr) {
967 uint64_t next_inst_size = 0;
968 llvm::MCInst mc_insn;
969 llvm::MCDisassembler::DecodeStatus decode_status;
974 mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls());
976 decode_status =
m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
977 inst_addr, llvm::nulls());
979 if (decode_status != llvm::MCDisassembler::Success)
982 return m_insn_info->get(mc_insn.getOpcode()).getSize();
1001 uint32_t current_inst_size = insn_opcode.
GetByteSize();
1002 uint8_t buf[
sizeof(uint32_t)];
1003 uint64_t next_inst_addr = (
m_addr & (~1ull)) + current_inst_size;
1004 Address next_addr(next_inst_addr);
1006 const size_t bytes_read = target->
ReadMemory(
1008 buf,
sizeof(uint32_t),
error,
false,
1011 if (bytes_read == 0)
1032 bool success =
false;
1049 bool success =
false;
1050 llvm::MCInst mc_insn;
1057 llvm::MCDisassembler::DecodeStatus decode_status;
1060 decode_status =
m_alt_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1063 decode_status =
m_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1066 if (decode_status != llvm::MCDisassembler::Success)
1074 const char *op_name =
m_insn_info->getName(mc_insn.getOpcode()).data();
1076 if (op_name ==
nullptr)
1085 if (opcode_data ==
nullptr)
1088 uint64_t old_pc = 0, new_pc = 0;
1089 const bool auto_advance_pc =
1090 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1092 if (auto_advance_pc) {
1100 success = (this->*opcode_data->
callback)(mc_insn);
1104 if (auto_advance_pc) {
1111 if (old_pc == new_pc) {
1125 unwind_plan.
Clear();
1129 const bool can_replace =
false;
1175 bool success =
false;
1176 const uint32_t imm16 = insn.getOperand(2).getImm();
1179 dst =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1180 src =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1197 uint64_t result = src_opd_val + imm;
1198 std::optional<RegisterInfo> reg_info_sp =
1223 bool success =
false;
1224 uint32_t imm16 = insn.getOperand(2).getImm();
1230 src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1231 base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1233 std::optional<RegisterInfo> reg_info_base =
1245 address = address + imm;
1254 std::optional<RegisterInfo> reg_info_src =
1266 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1270 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1275 if (!
WriteMemory(context, address, buffer.data(), reg_info_src->byte_size))
1285 bool success =
false;
1287 int32_t imm, address;
1290 src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1291 base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1292 imm = insn.getOperand(2).getImm();
1304 address = address + imm;
1313 std::optional<RegisterInfo> reg_info_src =
1333 bool success =
false;
1335 uint8_t src, dst, rt;
1336 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1338 dst =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1339 src =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1343 rt =
m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1357 if (op_name.equals_insensitive(
"SUBU"))
1358 result = src_opd_val - rt_opd_val;
1360 result = src_opd_val + rt_opd_val;
1363 std::optional<RegisterInfo> reg_info_sp =
1375 rt =
m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1391 if (op_name.equals_insensitive(
"SUBU"))
1392 result = src_opd_val - rt_opd_val;
1394 result = src_opd_val + rt_opd_val;
1411 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1416 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1425 bool success =
false;
1426 const uint32_t imm9 = insn.getOperand(0).getImm();
1431 uint64_t src_opd_val =
1436 result = src_opd_val + imm9;
1439 std::optional<RegisterInfo> reg_info_sp =
1452 bool success =
false;
1454 const uint32_t imm4 = insn.getOperand(2).getImm();
1458 base =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1468 result = src_opd_val + imm4;
1471 std::optional<RegisterInfo> reg_info_sp =
1486 bool success =
false;
1487 uint32_t imm5 = insn.getOperand(2).getImm();
1492 src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1493 base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1495 std::optional<RegisterInfo> reg_info_base =
1507 address = address + imm5;
1526 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1530 if (data_src->GetAsMemoryData(reg_info_src, buffer.
data(),
1551 bool success =
false;
1553 uint32_t num_operands = insn.getNumOperands();
1558 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1566 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1568 std::optional<RegisterInfo> reg_info_base =
1580 base_address = base_address + offset;
1583 for (uint32_t i = 0; i < num_operands - 2; i++) {
1585 src =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1597 std::optional<RegisterInfo> reg_info_src =
1609 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1613 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1618 if (!
WriteMemory(context, base_address, buffer.data(),
1619 reg_info_src->byte_size))
1623 base_address = base_address + reg_info_src->byte_size;
1629 bool success =
false;
1630 uint32_t src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1631 uint32_t base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1632 uint32_t imm5 = insn.getOperand(2).getImm();
1644 base_address = base_address + imm5;
1655 std::optional<RegisterInfo> reg_info_src =
1677 bool success =
false;
1679 uint32_t num_operands = insn.getNumOperands();
1681 uint32_t imm = insn.getOperand(num_operands - 1)
1686 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1698 base_address = base_address + imm;
1703 for (uint32_t i = 0; i < num_operands - 2; i++) {
1705 dst =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1717 std::optional<RegisterInfo> reg_info_dst =
1734 bool success =
false;
1735 int32_t imm5 = insn.getOperand(0).getImm();
1744 int32_t src_opd_val =
1754 int32_t result = src_opd_val + imm5;
1763 std::optional<RegisterInfo> reg_info_sp =
1777 int32_t r = (uint32_t)a + (uint32_t)b;
1778 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1787 bool success =
false;
1789 int32_t offset,
pc, target = 0, rs_val, rt_val;
1790 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1792 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1793 rt =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1794 offset = insn.getOperand(2).getImm();
1810 if (op_name.equals_insensitive(
"BEQ") || op_name.equals_insensitive(
"BEQL")) {
1811 if (rs_val == rt_val)
1812 target =
pc + offset;
1815 }
else if (op_name.equals_insensitive(
"BNE") ||
1816 op_name.equals_insensitive(
"BNEL")) {
1817 if (rs_val != rt_val)
1818 target =
pc + offset;
1837 bool success =
false;
1839 int32_t offset,
pc, target = 0, rs_val, rt_val;
1840 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1841 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
1843 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1844 rt =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1845 offset = insn.getOperand(2).getImm();
1861 if (op_name.equals_insensitive(
"BEQC")) {
1862 if (rs_val == rt_val)
1863 target =
pc + offset;
1866 }
else if (op_name.equals_insensitive(
"BNEC")) {
1867 if (rs_val != rt_val)
1868 target =
pc + offset;
1871 }
else if (op_name.equals_insensitive(
"BLTC")) {
1872 if (rs_val < rt_val)
1873 target =
pc + offset;
1876 }
else if (op_name.equals_insensitive(
"BGEC")) {
1877 if (rs_val >= rt_val)
1878 target =
pc + offset;
1881 }
else if (op_name.equals_insensitive(
"BLTUC")) {
1882 if (rs_val < rt_val)
1883 target =
pc + offset;
1886 }
else if (op_name.equals_insensitive(
"BGEUC")) {
1887 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1888 target =
pc + offset;
1891 }
else if (op_name.equals_insensitive(
"BOVC")) {
1893 target =
pc + offset;
1896 }
else if (op_name.equals_insensitive(
"BNVC")) {
1898 target =
pc + offset;
1916 bool success =
false;
1918 int32_t offset,
pc, target = 0;
1920 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1922 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1923 offset = insn.getOperand(1).getImm();
1934 if (op_name.equals_insensitive(
"BLEZALC")) {
1936 target =
pc + offset;
1939 }
else if (op_name.equals_insensitive(
"BGEZALC")) {
1941 target =
pc + offset;
1944 }
else if (op_name.equals_insensitive(
"BLTZALC")) {
1946 target =
pc + offset;
1949 }
else if (op_name.equals_insensitive(
"BGTZALC")) {
1951 target =
pc + offset;
1954 }
else if (op_name.equals_insensitive(
"BEQZALC")) {
1956 target =
pc + offset;
1959 }
else if (op_name.equals_insensitive(
"BNEZALC")) {
1961 target =
pc + offset;
1985 bool success =
false;
1987 int32_t offset,
pc, target = 0;
1989 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1991 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1992 offset = insn.getOperand(1).getImm();
2003 if (op_name.equals_insensitive(
"BLTZAL") ||
2004 op_name.equals_insensitive(
"BLTZALL")) {
2005 if ((int32_t)rs_val < 0)
2006 target =
pc + offset;
2009 }
else if (op_name.equals_insensitive(
"BGEZAL") ||
2010 op_name.equals_insensitive(
"BGEZALL")) {
2011 if ((int32_t)rs_val >= 0)
2012 target =
pc + offset;
2036 bool success =
false;
2038 int32_t offset,
pc, target = 0;
2040 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2042 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2043 offset = insn.getOperand(1).getImm();
2054 if (op_name.equals_insensitive(
"BLTZL") ||
2055 op_name.equals_insensitive(
"BLTZ")) {
2057 target =
pc + offset;
2060 }
else if (op_name.equals_insensitive(
"BGEZL") ||
2061 op_name.equals_insensitive(
"BGEZ")) {
2063 target =
pc + offset;
2066 }
else if (op_name.equals_insensitive(
"BGTZL") ||
2067 op_name.equals_insensitive(
"BGTZ")) {
2069 target =
pc + offset;
2072 }
else if (op_name.equals_insensitive(
"BLEZL") ||
2073 op_name.equals_insensitive(
"BLEZ")) {
2075 target =
pc + offset;
2093 bool success =
false;
2095 int32_t offset,
pc, target = 0;
2097 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2098 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
2100 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2101 offset = insn.getOperand(1).getImm();
2112 if (op_name.equals_insensitive(
"BLTZC")) {
2114 target =
pc + offset;
2117 }
else if (op_name.equals_insensitive(
"BLEZC")) {
2119 target =
pc + offset;
2122 }
else if (op_name.equals_insensitive(
"BGEZC")) {
2124 target =
pc + offset;
2127 }
else if (op_name.equals_insensitive(
"BGTZC")) {
2129 target =
pc + offset;
2132 }
else if (op_name.equals_insensitive(
"BEQZC")) {
2134 target =
pc + offset;
2137 }
else if (op_name.equals_insensitive(
"BNEZC")) {
2139 target =
pc + offset;
2153 bool success =
false;
2154 int32_t offset,
pc, target;
2155 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
2157 offset = insn.getOperand(0).getImm();
2164 target =
pc + offset;
2180 bool success =
false;
2182 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
2183 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2184 bool update_ra =
false;
2185 uint32_t ra_offset = 0;
2204 uint32_t rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2205 int32_t offset = insn.getOperand(1).getImm();
2217 if (op_name.equals_insensitive(
"BEQZ16_MM")) {
2219 target =
pc + offset;
2221 target =
pc + current_inst_size +
2223 }
else if (op_name.equals_insensitive(
"BNEZ16_MM")) {
2225 target =
pc + offset;
2227 target =
pc + current_inst_size +
2229 }
else if (op_name.equals_insensitive(
"BEQZC_MM")) {
2231 target =
pc + 4 + offset;
2236 }
else if (op_name.equals_insensitive(
"BNEZC_MM")) {
2238 target =
pc + 4 + offset;
2243 }
else if (op_name.equals_insensitive(
"BGEZALS_MM")) {
2245 target =
pc + offset;
2251 }
else if (op_name.equals_insensitive(
"BLTZALS_MM")) {
2253 target =
pc + offset;
2281 bool success =
false;
2282 uint32_t ra_offset = 0;
2283 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2285 uint32_t rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2297 if (op_name.equals_insensitive(
"JALR16_MM"))
2299 else if (op_name.equals_insensitive(
"JALRS16_MM"))
2320 bool success =
false;
2321 uint32_t offset = 0, target = 0,
pc = 0, ra_offset = 0;
2322 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2334 offset = insn.getOperand(0).getImm();
2341 if (op_name.equals_insensitive(
"JALS_MM")) {
2343 target = (
pc & 0xF8000000UL) | offset;
2345 }
else if (op_name.equals_insensitive(
"JALX_MM")) {
2347 target = (
pc & 0xF0000000UL) | offset;
2365 bool success =
false;
2366 uint32_t rs = 0, rt = 0;
2367 int32_t
pc = 0, rs_val = 0;
2375 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2376 rs =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2402 bool success =
false;
2403 int32_t offset,
pc, target;
2411 offset = insn.getOperand(0).getImm();
2417 target =
pc + offset;
2433 bool success =
false;
2434 int32_t offset,
pc, target;
2442 offset = insn.getOperand(0).getImm();
2448 target =
pc + offset;
2464 bool success =
false;
2465 int32_t offset,
pc, target;
2472 offset = insn.getOperand(0).getImm();
2478 target =
pc + offset;
2487 bool success =
false;
2488 uint32_t offset,
pc;
2495 offset = insn.getOperand(0).getImm();
2502 pc = (
pc & 0xF0000000UL) | offset;
2510 bool success =
false;
2511 uint32_t offset, target,
pc;
2518 offset = insn.getOperand(0).getImm();
2525 target = (
pc & 0xF0000000UL) | offset;
2541 bool success =
false;
2543 uint32_t
pc, rs_val;
2550 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2551 rs =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2576 bool success =
false;
2578 int32_t target, offset,
pc, rt_val;
2586 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2587 offset = insn.getOperand(1).getImm();
2598 target = rt_val + offset;
2614 bool success =
false;
2616 int32_t target, offset, rt_val;
2623 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2624 offset = insn.getOperand(1).getImm();
2631 target = rt_val + offset;
2640 bool success =
false;
2648 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2667 bool success =
false;
2669 int32_t
pc, offset, target = 0;
2670 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2672 cc =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2673 offset = insn.getOperand(1).getImm();
2684 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2686 if (op_name.equals_insensitive(
"BC1F") ||
2687 op_name.equals_insensitive(
"BC1FL")) {
2688 if ((fcsr & (1 << cc)) == 0)
2689 target =
pc + offset;
2692 }
else if (op_name.equals_insensitive(
"BC1T") ||
2693 op_name.equals_insensitive(
"BC1TL")) {
2694 if ((fcsr & (1 << cc)) != 0)
2695 target =
pc + offset;
2706 bool success =
false;
2709 int32_t target,
pc, offset;
2718 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2719 offset = insn.getOperand(1).getImm();
2730 if ((ft_val & 1) == 0)
2731 target =
pc + 4 + offset;
2742 bool success =
false;
2745 int32_t target,
pc, offset;
2754 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2755 offset = insn.getOperand(1).getImm();
2766 if ((ft_val & 1) != 0)
2767 target =
pc + 4 + offset;
2785 bool success =
false;
2787 int32_t
pc, offset, target = 0;
2788 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2790 cc =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2791 offset = insn.getOperand(1).getImm();
2803 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2805 if (op_name.equals_insensitive(
"BC1ANY2F")) {
2807 if (((fcsr >> cc) & 3) != 3)
2808 target =
pc + offset;
2811 }
else if (op_name.equals_insensitive(
"BC1ANY2T")) {
2813 if (((fcsr >> cc) & 3) != 0)
2814 target =
pc + offset;
2817 }
else if (op_name.equals_insensitive(
"BC1ANY4F")) {
2819 if (((fcsr >> cc) & 0xf) != 0xf)
2820 target =
pc + offset;
2823 }
else if (op_name.equals_insensitive(
"BC1ANY4T")) {
2825 if (((fcsr >> cc) & 0xf) != 0)
2826 target =
pc + offset;
2869 int element_byte_size,
2871 bool success =
false, branch_hit =
true;
2874 const uint8_t *ptr =
nullptr;
2876 uint32_t wt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2877 int32_t offset = insn.getOperand(1).getImm();
2885 ptr = (
const uint8_t *)reg_value.
GetBytes();
2889 for (
int i = 0; i < 16 / element_byte_size; i++) {
2890 switch (element_byte_size) {
2892 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2896 if ((*(
const uint16_t *)ptr == 0 && bnz) ||
2897 (*(
const uint16_t *)ptr != 0 && !bnz))
2901 if ((*(
const uint32_t *)ptr == 0 && bnz) ||
2902 (*(
const uint32_t *)ptr != 0 && !bnz))
2906 if ((*(
const uint64_t *)ptr == 0 && bnz) ||
2907 (*(
const uint64_t *)ptr != 0 && !bnz))
2913 ptr = ptr + element_byte_size;
2917 target =
pc + offset;
2938 bool success =
false;
2940 llvm::APInt wr_val = llvm::APInt::getZero(128);
2941 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2942 llvm::APInt zero_value = llvm::APInt::getZero(128);
2945 uint32_t wt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2946 int32_t offset = insn.getOperand(1).getImm();
2958 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2959 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2960 target =
pc + offset;
2972 bool success =
false;
2974 int32_t imm, address;
2977 uint32_t num_operands = insn.getNumOperands();
2979 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2980 imm = insn.getOperand(num_operands - 1).getImm();
2992 address = address + imm;
3003 bool success =
false;
3004 uint32_t base, index;
3005 int32_t address, index_address;
3008 uint32_t num_operands = insn.getNumOperands();
3010 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3012 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3033 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)
EmulateInstruction(const ArchSpec &arch)
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
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, bool *did_read_live_memory=nullptr)
void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
const FAValue & GetCFAValue() const
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
void SetRegisterKind(lldb::RegisterKind kind)
void SetReturnAddressRegister(uint32_t regnum)
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.