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));
157 m_subtype_info.reset(target->createMCSubtargetInfo(triple, cpu, features));
160 m_context = std::make_unique<llvm::MCContext>(
169 features +=
"+mips16,";
171 features +=
"+micromips,";
174 target->createMCSubtargetInfo(triple, cpu, features));
195 return "Emulate instructions for the MIPS32 architecture.";
203 if (arch.
GetTriple().getArch() == llvm::Triple::mips ||
204 arch.
GetTriple().getArch() == llvm::Triple::mipsel) {
213 return arch.
GetTriple().getArch() == llvm::Triple::mips ||
214 arch.
GetTriple().getArch() == llvm::Triple::mipsel;
218 bool alternate_name) {
219 if (alternate_name) {
586std::optional<RegisterInfo>
674 "ADDIU rt, rs, immediate"},
685 "ADDIUS5 rd,immediate"},
688 "SWM16 reglist,offset(sp)"},
690 "SWM32 reglist,offset(base)"},
692 "SWP rs1,offset(base)"},
695 "LWM16 reglist,offset(sp)"},
697 "LWM32 reglist,offset(base)"},
699 "LWP rd,offset(base)"},
701 "JRADDIUSP immediate"},
712 "LB rt, offset(base)"},
714 "LBE rt, offset(base)"},
716 "LBU rt, offset(base)"},
718 "LBUE rt, offset(base)"},
720 "LDC1 ft, offset(base)"},
722 "LD rt, offset(base)"},
724 "LDL rt, offset(base)"},
726 "LDR rt, offset(base)"},
728 "LLD rt, offset(base)"},
730 "LDC2 rt, offset(base)"},
732 "LDXC1 fd, index (base)"},
734 "LH rt, offset(base)"},
736 "LHE rt, offset(base)"},
738 "LHU rt, offset(base)"},
740 "LHUE rt, offset(base)"},
742 "LL rt, offset(base)"},
744 "LLE rt, offset(base)"},
746 "LUXC1 fd, index (base)"},
748 "LW rt, offset(base)"},
750 "LWC1 ft, offset(base)"},
752 "LWC2 rt, offset(base)"},
754 "LWE rt, offset(base)"},
756 "LWL rt, offset(base)"},
758 "LWLE rt, offset(base)"},
760 "LWR rt, offset(base)"},
762 "LWRE rt, offset(base)"},
764 "LWXC1 fd, index (base)"},
766 "LLX rt, offset(base)"},
768 "LLXE rt, offset(base)"},
770 "LLDX rt, offset(base)"},
773 "SB rt, offset(base)"},
775 "SBE rt, offset(base)"},
777 "SC rt, offset(base)"},
779 "SCE rt, offset(base)"},
781 "SCD rt, offset(base)"},
783 "SD rt, offset(base)"},
785 "SDL rt, offset(base)"},
787 "SDR rt, offset(base)"},
789 "SDC1 ft, offset(base)"},
791 "SDC2 rt, offset(base)"},
793 "SDXC1 fs, index(base)"},
795 "SH rt, offset(base)"},
797 "SHE rt, offset(base)"},
799 "SUXC1 fs, index (base)"},
801 "SWC1 ft, offset(base)"},
803 "SWC2 rt, offset(base)"},
805 "SWE rt, offset(base)"},
807 "SWL rt, offset(base)"},
809 "SWLE rt, offset(base)"},
811 "SWR rt, offset(base)"},
813 "SWRE rt, offset(base)"},
815 "SWXC1 fs, index (base)"},
817 "SCX rt, offset(base)"},
819 "SCXE rt, offset(base)"},
821 "SCDX rt, offset(base)"},
825 "LBU16 rt, decoded_offset(base)"},
827 "LHU16 rt, left_shifted_offset(base)"},
829 "LW16 rt, left_shifted_offset(base)"},
831 "LWGP rt, left_shifted_offset(gp)"},
833 "SH16 rt, left_shifted_offset(base)"},
835 "SW16 rt, left_shifted_offset(base)"},
837 "SWSP rt, left_shifted_offset(base)"},
839 "SB16 rt, offset(base)"},
847 "BGEZALL rt,offset"},
855 "BLEZALC rs,offset"},
857 "BGEZALC rs,offset"},
859 "BLTZALC rs,offset"},
861 "BGTZALC rs,offset"},
863 "BEQZALC rs,offset"},
865 "BNEZALC rs,offset"},
867 "BEQC rs,rt,offset"},
869 "BNEC rs,rt,offset"},
871 "BLTC rs,rt,offset"},
873 "BGEC rs,rt,offset"},
875 "BLTUC rs,rt,offset"},
877 "BGEUC rs,rt,offset"},
893 "BLTZALL rt,offset"},
896 "BOVC rs,rt,offset"},
898 "BNVC rs,rt,offset"},
915 "BC1ANY2F cc, offset"},
917 "BC1ANY2T cc, offset"},
919 "BC1ANY4F cc, offset"},
921 "BC1ANY4T cc, offset"},
936 "BEQZ16 rs, offset"},
938 "BNEZ16 rs, offset"},
944 "BGEZALS rs, offset"},
946 "BLTZALS rs, offset"},
957 if (name.equals_insensitive(opcode.op_name))
965 uint64_t inst_addr) {
966 uint64_t next_inst_size = 0;
967 llvm::MCInst mc_insn;
968 llvm::MCDisassembler::DecodeStatus decode_status;
973 mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls());
975 decode_status =
m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
976 inst_addr, llvm::nulls());
978 if (decode_status != llvm::MCDisassembler::Success)
981 return m_insn_info->get(mc_insn.getOpcode()).getSize();
1000 uint32_t current_inst_size = insn_opcode.
GetByteSize();
1001 uint8_t buf[
sizeof(uint32_t)];
1002 uint64_t next_inst_addr = (
m_addr & (~1ull)) + current_inst_size;
1003 Address next_addr(next_inst_addr);
1005 const size_t bytes_read = target->
ReadMemory(
1007 buf,
sizeof(uint32_t),
error,
false,
1010 if (bytes_read == 0)
1031 bool success =
false;
1048 bool success =
false;
1049 llvm::MCInst mc_insn;
1056 llvm::MCDisassembler::DecodeStatus decode_status;
1059 decode_status =
m_alt_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1062 decode_status =
m_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1065 if (decode_status != llvm::MCDisassembler::Success)
1073 const char *op_name =
m_insn_info->getName(mc_insn.getOpcode()).data();
1075 if (op_name ==
nullptr)
1084 if (opcode_data ==
nullptr)
1087 uint64_t old_pc = 0, new_pc = 0;
1088 const bool auto_advance_pc =
1089 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1091 if (auto_advance_pc) {
1099 success = (this->*opcode_data->
callback)(mc_insn);
1103 if (auto_advance_pc) {
1110 if (old_pc == new_pc) {
1124 unwind_plan.
Clear();
1128 const bool can_replace =
false;
1174 bool success =
false;
1175 const uint32_t imm16 = insn.getOperand(2).getImm();
1178 dst =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1179 src =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1196 uint64_t result = src_opd_val + imm;
1197 std::optional<RegisterInfo> reg_info_sp =
1222 bool success =
false;
1223 uint32_t imm16 = insn.getOperand(2).getImm();
1229 src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1230 base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1232 std::optional<RegisterInfo> reg_info_base =
1244 address = address + imm;
1253 std::optional<RegisterInfo> reg_info_src =
1265 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1269 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1274 if (!
WriteMemory(context, address, buffer.data(), reg_info_src->byte_size))
1284 bool success =
false;
1286 int32_t imm, address;
1289 src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1290 base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1291 imm = insn.getOperand(2).getImm();
1303 address = address + imm;
1312 std::optional<RegisterInfo> reg_info_src =
1332 bool success =
false;
1334 uint8_t src, dst, rt;
1335 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1337 dst =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1338 src =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1342 rt =
m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1356 if (op_name.equals_insensitive(
"SUBU"))
1357 result = src_opd_val - rt_opd_val;
1359 result = src_opd_val + rt_opd_val;
1362 std::optional<RegisterInfo> reg_info_sp =
1374 rt =
m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1390 if (op_name.equals_insensitive(
"SUBU"))
1391 result = src_opd_val - rt_opd_val;
1393 result = src_opd_val + rt_opd_val;
1410 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1415 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1424 bool success =
false;
1425 const uint32_t imm9 = insn.getOperand(0).getImm();
1430 uint64_t src_opd_val =
1435 result = src_opd_val + imm9;
1438 std::optional<RegisterInfo> reg_info_sp =
1451 bool success =
false;
1453 const uint32_t imm4 = insn.getOperand(2).getImm();
1457 base =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1467 result = src_opd_val + imm4;
1470 std::optional<RegisterInfo> reg_info_sp =
1485 bool success =
false;
1486 uint32_t imm5 = insn.getOperand(2).getImm();
1491 src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1492 base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1494 std::optional<RegisterInfo> reg_info_base =
1506 address = address + imm5;
1525 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1529 if (data_src->GetAsMemoryData(reg_info_src, buffer.
data(),
1550 bool success =
false;
1552 uint32_t num_operands = insn.getNumOperands();
1557 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1565 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1567 std::optional<RegisterInfo> reg_info_base =
1579 base_address = base_address + offset;
1582 for (uint32_t i = 0; i < num_operands - 2; i++) {
1584 src =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1596 std::optional<RegisterInfo> reg_info_src =
1608 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1612 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(),
1617 if (!
WriteMemory(context, base_address, buffer.data(),
1618 reg_info_src->byte_size))
1622 base_address = base_address + reg_info_src->byte_size;
1628 bool success =
false;
1629 uint32_t src =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1630 uint32_t base =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1631 uint32_t imm5 = insn.getOperand(2).getImm();
1643 base_address = base_address + imm5;
1654 std::optional<RegisterInfo> reg_info_src =
1676 bool success =
false;
1678 uint32_t num_operands = insn.getNumOperands();
1680 uint32_t imm = insn.getOperand(num_operands - 1)
1685 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1697 base_address = base_address + imm;
1702 for (uint32_t i = 0; i < num_operands - 2; i++) {
1704 dst =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1716 std::optional<RegisterInfo> reg_info_dst =
1733 bool success =
false;
1734 int32_t imm5 = insn.getOperand(0).getImm();
1743 int32_t src_opd_val =
1753 int32_t result = src_opd_val + imm5;
1762 std::optional<RegisterInfo> reg_info_sp =
1776 int32_t r = (uint32_t)a + (uint32_t)b;
1777 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1786 bool success =
false;
1788 int32_t offset,
pc, target = 0, rs_val, rt_val;
1789 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1791 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1792 rt =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1793 offset = insn.getOperand(2).getImm();
1809 if (op_name.equals_insensitive(
"BEQ") || op_name.equals_insensitive(
"BEQL")) {
1810 if (rs_val == rt_val)
1811 target =
pc + offset;
1814 }
else if (op_name.equals_insensitive(
"BNE") ||
1815 op_name.equals_insensitive(
"BNEL")) {
1816 if (rs_val != rt_val)
1817 target =
pc + offset;
1836 bool success =
false;
1838 int32_t offset,
pc, target = 0, rs_val, rt_val;
1839 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1840 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
1842 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1843 rt =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1844 offset = insn.getOperand(2).getImm();
1860 if (op_name.equals_insensitive(
"BEQC")) {
1861 if (rs_val == rt_val)
1862 target =
pc + offset;
1865 }
else if (op_name.equals_insensitive(
"BNEC")) {
1866 if (rs_val != rt_val)
1867 target =
pc + offset;
1870 }
else if (op_name.equals_insensitive(
"BLTC")) {
1871 if (rs_val < rt_val)
1872 target =
pc + offset;
1875 }
else if (op_name.equals_insensitive(
"BGEC")) {
1876 if (rs_val >= rt_val)
1877 target =
pc + offset;
1880 }
else if (op_name.equals_insensitive(
"BLTUC")) {
1881 if (rs_val < rt_val)
1882 target =
pc + offset;
1885 }
else if (op_name.equals_insensitive(
"BGEUC")) {
1886 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1887 target =
pc + offset;
1890 }
else if (op_name.equals_insensitive(
"BOVC")) {
1892 target =
pc + offset;
1895 }
else if (op_name.equals_insensitive(
"BNVC")) {
1897 target =
pc + offset;
1915 bool success =
false;
1917 int32_t offset,
pc, target = 0;
1919 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1921 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1922 offset = insn.getOperand(1).getImm();
1933 if (op_name.equals_insensitive(
"BLEZALC")) {
1935 target =
pc + offset;
1938 }
else if (op_name.equals_insensitive(
"BGEZALC")) {
1940 target =
pc + offset;
1943 }
else if (op_name.equals_insensitive(
"BLTZALC")) {
1945 target =
pc + offset;
1948 }
else if (op_name.equals_insensitive(
"BGTZALC")) {
1950 target =
pc + offset;
1953 }
else if (op_name.equals_insensitive(
"BEQZALC")) {
1955 target =
pc + offset;
1958 }
else if (op_name.equals_insensitive(
"BNEZALC")) {
1960 target =
pc + offset;
1984 bool success =
false;
1986 int32_t offset,
pc, target = 0;
1988 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1990 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1991 offset = insn.getOperand(1).getImm();
2002 if (op_name.equals_insensitive(
"BLTZAL") ||
2003 op_name.equals_insensitive(
"BLTZALL")) {
2004 if ((int32_t)rs_val < 0)
2005 target =
pc + offset;
2008 }
else if (op_name.equals_insensitive(
"BGEZAL") ||
2009 op_name.equals_insensitive(
"BGEZALL")) {
2010 if ((int32_t)rs_val >= 0)
2011 target =
pc + offset;
2035 bool success =
false;
2037 int32_t offset,
pc, target = 0;
2039 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2041 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2042 offset = insn.getOperand(1).getImm();
2053 if (op_name.equals_insensitive(
"BLTZL") ||
2054 op_name.equals_insensitive(
"BLTZ")) {
2056 target =
pc + offset;
2059 }
else if (op_name.equals_insensitive(
"BGEZL") ||
2060 op_name.equals_insensitive(
"BGEZ")) {
2062 target =
pc + offset;
2065 }
else if (op_name.equals_insensitive(
"BGTZL") ||
2066 op_name.equals_insensitive(
"BGTZ")) {
2068 target =
pc + offset;
2071 }
else if (op_name.equals_insensitive(
"BLEZL") ||
2072 op_name.equals_insensitive(
"BLEZ")) {
2074 target =
pc + offset;
2092 bool success =
false;
2094 int32_t offset,
pc, target = 0;
2096 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2097 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
2099 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2100 offset = insn.getOperand(1).getImm();
2111 if (op_name.equals_insensitive(
"BLTZC")) {
2113 target =
pc + offset;
2116 }
else if (op_name.equals_insensitive(
"BLEZC")) {
2118 target =
pc + offset;
2121 }
else if (op_name.equals_insensitive(
"BGEZC")) {
2123 target =
pc + offset;
2126 }
else if (op_name.equals_insensitive(
"BGTZC")) {
2128 target =
pc + offset;
2131 }
else if (op_name.equals_insensitive(
"BEQZC")) {
2133 target =
pc + offset;
2136 }
else if (op_name.equals_insensitive(
"BNEZC")) {
2138 target =
pc + offset;
2152 bool success =
false;
2153 int32_t offset,
pc, target;
2154 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
2156 offset = insn.getOperand(0).getImm();
2163 target =
pc + offset;
2179 bool success =
false;
2181 uint32_t current_inst_size =
m_insn_info->get(insn.getOpcode()).getSize();
2182 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2183 bool update_ra =
false;
2184 uint32_t ra_offset = 0;
2203 uint32_t rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2204 int32_t offset = insn.getOperand(1).getImm();
2216 if (op_name.equals_insensitive(
"BEQZ16_MM")) {
2218 target =
pc + offset;
2220 target =
pc + current_inst_size +
2222 }
else if (op_name.equals_insensitive(
"BNEZ16_MM")) {
2224 target =
pc + offset;
2226 target =
pc + current_inst_size +
2228 }
else if (op_name.equals_insensitive(
"BEQZC_MM")) {
2230 target =
pc + 4 + offset;
2235 }
else if (op_name.equals_insensitive(
"BNEZC_MM")) {
2237 target =
pc + 4 + offset;
2242 }
else if (op_name.equals_insensitive(
"BGEZALS_MM")) {
2244 target =
pc + offset;
2250 }
else if (op_name.equals_insensitive(
"BLTZALS_MM")) {
2252 target =
pc + offset;
2280 bool success =
false;
2281 uint32_t ra_offset = 0;
2282 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2284 uint32_t rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2296 if (op_name.equals_insensitive(
"JALR16_MM"))
2298 else if (op_name.equals_insensitive(
"JALRS16_MM"))
2319 bool success =
false;
2320 uint32_t offset = 0, target = 0,
pc = 0, ra_offset = 0;
2321 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2333 offset = insn.getOperand(0).getImm();
2340 if (op_name.equals_insensitive(
"JALS_MM")) {
2342 target = (
pc & 0xF8000000UL) | offset;
2344 }
else if (op_name.equals_insensitive(
"JALX_MM")) {
2346 target = (
pc & 0xF0000000UL) | offset;
2364 bool success =
false;
2365 uint32_t rs = 0, rt = 0;
2366 int32_t
pc = 0, rs_val = 0;
2374 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2375 rs =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2401 bool success =
false;
2402 int32_t offset,
pc, target;
2410 offset = insn.getOperand(0).getImm();
2416 target =
pc + offset;
2432 bool success =
false;
2433 int32_t offset,
pc, target;
2441 offset = insn.getOperand(0).getImm();
2447 target =
pc + offset;
2463 bool success =
false;
2464 int32_t offset,
pc, target;
2471 offset = insn.getOperand(0).getImm();
2477 target =
pc + offset;
2486 bool success =
false;
2487 uint32_t offset,
pc;
2494 offset = insn.getOperand(0).getImm();
2501 pc = (
pc & 0xF0000000UL) | offset;
2509 bool success =
false;
2510 uint32_t offset, target,
pc;
2517 offset = insn.getOperand(0).getImm();
2524 target = (
pc & 0xF0000000UL) | offset;
2540 bool success =
false;
2542 uint32_t
pc, rs_val;
2549 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2550 rs =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2575 bool success =
false;
2577 int32_t target, offset,
pc, rt_val;
2585 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2586 offset = insn.getOperand(1).getImm();
2597 target = rt_val + offset;
2613 bool success =
false;
2615 int32_t target, offset, rt_val;
2622 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2623 offset = insn.getOperand(1).getImm();
2630 target = rt_val + offset;
2639 bool success =
false;
2647 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2666 bool success =
false;
2668 int32_t
pc, offset, target = 0;
2669 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2671 cc =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2672 offset = insn.getOperand(1).getImm();
2683 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2685 if (op_name.equals_insensitive(
"BC1F") ||
2686 op_name.equals_insensitive(
"BC1FL")) {
2687 if ((fcsr & (1 << cc)) == 0)
2688 target =
pc + offset;
2691 }
else if (op_name.equals_insensitive(
"BC1T") ||
2692 op_name.equals_insensitive(
"BC1TL")) {
2693 if ((fcsr & (1 << cc)) != 0)
2694 target =
pc + offset;
2705 bool success =
false;
2708 int32_t target,
pc, offset;
2717 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2718 offset = insn.getOperand(1).getImm();
2729 if ((ft_val & 1) == 0)
2730 target =
pc + 4 + offset;
2741 bool success =
false;
2744 int32_t target,
pc, offset;
2753 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2754 offset = insn.getOperand(1).getImm();
2765 if ((ft_val & 1) != 0)
2766 target =
pc + 4 + offset;
2784 bool success =
false;
2786 int32_t
pc, offset, target = 0;
2787 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2789 cc =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2790 offset = insn.getOperand(1).getImm();
2802 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2804 if (op_name.equals_insensitive(
"BC1ANY2F")) {
2806 if (((fcsr >> cc) & 3) != 3)
2807 target =
pc + offset;
2810 }
else if (op_name.equals_insensitive(
"BC1ANY2T")) {
2812 if (((fcsr >> cc) & 3) != 0)
2813 target =
pc + offset;
2816 }
else if (op_name.equals_insensitive(
"BC1ANY4F")) {
2818 if (((fcsr >> cc) & 0xf) != 0xf)
2819 target =
pc + offset;
2822 }
else if (op_name.equals_insensitive(
"BC1ANY4T")) {
2824 if (((fcsr >> cc) & 0xf) != 0)
2825 target =
pc + offset;
2868 int element_byte_size,
2870 bool success =
false, branch_hit =
true;
2873 const uint8_t *ptr =
nullptr;
2875 uint32_t wt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2876 int32_t offset = insn.getOperand(1).getImm();
2884 ptr = (
const uint8_t *)reg_value.
GetBytes();
2888 for (
int i = 0; i < 16 / element_byte_size; i++) {
2889 switch (element_byte_size) {
2891 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2895 if ((*(
const uint16_t *)ptr == 0 && bnz) ||
2896 (*(
const uint16_t *)ptr != 0 && !bnz))
2900 if ((*(
const uint32_t *)ptr == 0 && bnz) ||
2901 (*(
const uint32_t *)ptr != 0 && !bnz))
2905 if ((*(
const uint64_t *)ptr == 0 && bnz) ||
2906 (*(
const uint64_t *)ptr != 0 && !bnz))
2912 ptr = ptr + element_byte_size;
2916 target =
pc + offset;
2937 bool success =
false;
2939 llvm::APInt wr_val = llvm::APInt::getZero(128);
2940 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2941 llvm::APInt zero_value = llvm::APInt::getZero(128);
2944 uint32_t wt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2945 int32_t offset = insn.getOperand(1).getImm();
2957 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2958 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2959 target =
pc + offset;
2971 bool success =
false;
2973 int32_t imm, address;
2976 uint32_t num_operands = insn.getNumOperands();
2978 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2979 imm = insn.getOperand(num_operands - 1).getImm();
2991 address = address + imm;
3002 bool success =
false;
3003 uint32_t base, index;
3004 int32_t address, index_address;
3007 uint32_t num_operands = insn.getNumOperands();
3009 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3011 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3032 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)
llvm::MCTargetOptions m_mc_options
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.