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;
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>
620 RegisterInfo reg_info;
621 ::memset(®_info, 0,
sizeof(RegisterInfo));
627 reg_info.byte_size = 4;
632 reg_info.byte_size = 4;
637 reg_info.byte_size = 16;
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();
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 =
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,
1278 if (!
WriteMemory(context, address, buffer, 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;
1521 RegisterInfo reg_info_src = {};
1529 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1533 if (data_src->GetAsMemoryData(reg_info_src, buffer, reg_info_src.byte_size,
1537 if (!
WriteMemory(context, address, buffer, reg_info_src.byte_size))
1553 bool success =
false;
1555 uint32_t num_operands = insn.getNumOperands();
1560 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1568 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1570 std::optional<RegisterInfo> reg_info_base =
1582 base_address = base_address + offset;
1585 for (
uint32_t i = 0; i < num_operands - 2; i++) {
1587 src =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1599 std::optional<RegisterInfo> reg_info_src =
1611 std::optional<RegisterValue> data_src =
ReadRegister(*reg_info_base);
1615 if (data_src->GetAsMemoryData(*reg_info_src, buffer,
1620 if (!
WriteMemory(context, base_address, buffer, reg_info_src->byte_size))
1624 base_address = base_address + reg_info_src->byte_size;
1630 bool success =
false;
1633 uint32_t imm5 = insn.getOperand(2).getImm();
1645 base_address = base_address + imm5;
1656 std::optional<RegisterInfo> reg_info_src =
1678 bool success =
false;
1680 uint32_t num_operands = insn.getNumOperands();
1682 uint32_t imm = insn.getOperand(num_operands - 1)
1687 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1699 base_address = base_address + imm;
1704 for (
uint32_t i = 0; i < num_operands - 2; i++) {
1706 dst =
m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1718 std::optional<RegisterInfo> reg_info_dst =
1735 bool success =
false;
1736 int32_t imm5 = insn.getOperand(0).getImm();
1745 int32_t src_opd_val =
1755 int32_t result = src_opd_val + imm5;
1764 std::optional<RegisterInfo> reg_info_sp =
1779 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1788 bool success =
false;
1790 int32_t offset,
pc, target = 0, rs_val, rt_val;
1791 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1793 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1794 rt =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1795 offset = insn.getOperand(2).getImm();
1811 if (op_name.equals_insensitive(
"BEQ") || op_name.equals_insensitive(
"BEQL")) {
1812 if (rs_val == rt_val)
1813 target =
pc + offset;
1816 }
else if (op_name.equals_insensitive(
"BNE") ||
1817 op_name.equals_insensitive(
"BNEL")) {
1818 if (rs_val != rt_val)
1819 target =
pc + offset;
1838 bool success =
false;
1840 int32_t offset,
pc, target = 0, rs_val, rt_val;
1841 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1844 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1845 rt =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1846 offset = insn.getOperand(2).getImm();
1862 if (op_name.equals_insensitive(
"BEQC")) {
1863 if (rs_val == rt_val)
1864 target =
pc + offset;
1867 }
else if (op_name.equals_insensitive(
"BNEC")) {
1868 if (rs_val != rt_val)
1869 target =
pc + offset;
1872 }
else if (op_name.equals_insensitive(
"BLTC")) {
1873 if (rs_val < rt_val)
1874 target =
pc + offset;
1877 }
else if (op_name.equals_insensitive(
"BGEC")) {
1878 if (rs_val >= rt_val)
1879 target =
pc + offset;
1882 }
else if (op_name.equals_insensitive(
"BLTUC")) {
1883 if (rs_val < rt_val)
1884 target =
pc + offset;
1887 }
else if (op_name.equals_insensitive(
"BGEUC")) {
1889 target =
pc + offset;
1892 }
else if (op_name.equals_insensitive(
"BOVC")) {
1894 target =
pc + offset;
1897 }
else if (op_name.equals_insensitive(
"BNVC")) {
1899 target =
pc + offset;
1917 bool success =
false;
1919 int32_t offset,
pc, target = 0;
1921 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1923 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1924 offset = insn.getOperand(1).getImm();
1935 if (op_name.equals_insensitive(
"BLEZALC")) {
1937 target =
pc + offset;
1940 }
else if (op_name.equals_insensitive(
"BGEZALC")) {
1942 target =
pc + offset;
1945 }
else if (op_name.equals_insensitive(
"BLTZALC")) {
1947 target =
pc + offset;
1950 }
else if (op_name.equals_insensitive(
"BGTZALC")) {
1952 target =
pc + offset;
1955 }
else if (op_name.equals_insensitive(
"BEQZALC")) {
1957 target =
pc + offset;
1960 }
else if (op_name.equals_insensitive(
"BNEZALC")) {
1962 target =
pc + offset;
1986 bool success =
false;
1988 int32_t offset,
pc, target = 0;
1990 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
1992 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1993 offset = insn.getOperand(1).getImm();
2004 if (op_name.equals_insensitive(
"BLTZAL") ||
2005 op_name.equals_insensitive(
"BLTZALL")) {
2006 if ((int32_t)rs_val < 0)
2007 target =
pc + offset;
2010 }
else if (op_name.equals_insensitive(
"BGEZAL") ||
2011 op_name.equals_insensitive(
"BGEZALL")) {
2012 if ((int32_t)rs_val >= 0)
2013 target =
pc + offset;
2037 bool success =
false;
2039 int32_t offset,
pc, target = 0;
2041 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2043 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2044 offset = insn.getOperand(1).getImm();
2055 if (op_name.equals_insensitive(
"BLTZL") ||
2056 op_name.equals_insensitive(
"BLTZ")) {
2058 target =
pc + offset;
2061 }
else if (op_name.equals_insensitive(
"BGEZL") ||
2062 op_name.equals_insensitive(
"BGEZ")) {
2064 target =
pc + offset;
2067 }
else if (op_name.equals_insensitive(
"BGTZL") ||
2068 op_name.equals_insensitive(
"BGTZ")) {
2070 target =
pc + offset;
2073 }
else if (op_name.equals_insensitive(
"BLEZL") ||
2074 op_name.equals_insensitive(
"BLEZ")) {
2076 target =
pc + offset;
2094 bool success =
false;
2096 int32_t offset,
pc, target = 0;
2098 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2101 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2102 offset = insn.getOperand(1).getImm();
2113 if (op_name.equals_insensitive(
"BLTZC")) {
2115 target =
pc + offset;
2118 }
else if (op_name.equals_insensitive(
"BLEZC")) {
2120 target =
pc + offset;
2123 }
else if (op_name.equals_insensitive(
"BGEZC")) {
2125 target =
pc + offset;
2128 }
else if (op_name.equals_insensitive(
"BGTZC")) {
2130 target =
pc + offset;
2133 }
else if (op_name.equals_insensitive(
"BEQZC")) {
2135 target =
pc + offset;
2138 }
else if (op_name.equals_insensitive(
"BNEZC")) {
2140 target =
pc + offset;
2154 bool success =
false;
2155 int32_t offset,
pc, target;
2158 offset = insn.getOperand(0).getImm();
2165 target =
pc + offset;
2181 bool success =
false;
2184 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2185 bool update_ra =
false;
2206 int32_t offset = insn.getOperand(1).getImm();
2218 if (op_name.equals_insensitive(
"BEQZ16_MM")) {
2220 target =
pc + offset;
2222 target =
pc + current_inst_size +
2224 }
else if (op_name.equals_insensitive(
"BNEZ16_MM")) {
2226 target =
pc + offset;
2228 target =
pc + current_inst_size +
2230 }
else if (op_name.equals_insensitive(
"BEQZC_MM")) {
2232 target =
pc + 4 + offset;
2237 }
else if (op_name.equals_insensitive(
"BNEZC_MM")) {
2239 target =
pc + 4 + offset;
2244 }
else if (op_name.equals_insensitive(
"BGEZALS_MM")) {
2246 target =
pc + offset;
2252 }
else if (op_name.equals_insensitive(
"BLTZALS_MM")) {
2254 target =
pc + offset;
2282 bool success =
false;
2284 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2298 if (op_name.equals_insensitive(
"JALR16_MM"))
2300 else if (op_name.equals_insensitive(
"JALRS16_MM"))
2321 bool success =
false;
2322 uint32_t offset = 0, target = 0,
pc = 0, ra_offset = 0;
2323 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2335 offset = insn.getOperand(0).getImm();
2342 if (op_name.equals_insensitive(
"JALS_MM")) {
2344 target = (
pc & 0xF8000000UL) | offset;
2346 }
else if (op_name.equals_insensitive(
"JALX_MM")) {
2348 target = (
pc & 0xF0000000UL) | offset;
2366 bool success =
false;
2368 int32_t
pc = 0, rs_val = 0;
2376 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2377 rs =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2403 bool success =
false;
2404 int32_t offset,
pc, target;
2412 offset = insn.getOperand(0).getImm();
2418 target =
pc + offset;
2434 bool success =
false;
2435 int32_t offset,
pc, target;
2443 offset = insn.getOperand(0).getImm();
2449 target =
pc + offset;
2465 bool success =
false;
2466 int32_t offset,
pc, target;
2473 offset = insn.getOperand(0).getImm();
2479 target =
pc + offset;
2488 bool success =
false;
2496 offset = insn.getOperand(0).getImm();
2503 pc = (
pc & 0xF0000000UL) | offset;
2511 bool success =
false;
2519 offset = insn.getOperand(0).getImm();
2526 target = (
pc & 0xF0000000UL) | offset;
2542 bool success =
false;
2551 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2552 rs =
m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2577 bool success =
false;
2579 int32_t target, offset,
pc, rt_val;
2587 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2588 offset = insn.getOperand(1).getImm();
2599 target = rt_val + offset;
2615 bool success =
false;
2617 int32_t target, offset, rt_val;
2624 rt =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2625 offset = insn.getOperand(1).getImm();
2632 target = rt_val + offset;
2641 bool success =
false;
2649 rs =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2668 bool success =
false;
2670 int32_t
pc, offset, target = 0;
2671 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2673 cc =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2674 offset = insn.getOperand(1).getImm();
2685 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2687 if (op_name.equals_insensitive(
"BC1F") ||
2688 op_name.equals_insensitive(
"BC1FL")) {
2689 if ((fcsr & (1 << cc)) == 0)
2690 target =
pc + offset;
2693 }
else if (op_name.equals_insensitive(
"BC1T") ||
2694 op_name.equals_insensitive(
"BC1TL")) {
2695 if ((fcsr & (1 << cc)) != 0)
2696 target =
pc + offset;
2707 bool success =
false;
2710 int32_t target,
pc, offset;
2719 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2720 offset = insn.getOperand(1).getImm();
2731 if ((ft_val & 1) == 0)
2732 target =
pc + 4 + offset;
2743 bool success =
false;
2746 int32_t target,
pc, offset;
2755 ft =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2756 offset = insn.getOperand(1).getImm();
2767 if ((ft_val & 1) != 0)
2768 target =
pc + 4 + offset;
2786 bool success =
false;
2788 int32_t
pc, offset, target = 0;
2789 llvm::StringRef op_name =
m_insn_info->getName(insn.getOpcode());
2791 cc =
m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2792 offset = insn.getOperand(1).getImm();
2804 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2806 if (op_name.equals_insensitive(
"BC1ANY2F")) {
2808 if (((fcsr >> cc) & 3) != 3)
2809 target =
pc + offset;
2812 }
else if (op_name.equals_insensitive(
"BC1ANY2T")) {
2814 if (((fcsr >> cc) & 3) != 0)
2815 target =
pc + offset;
2818 }
else if (op_name.equals_insensitive(
"BC1ANY4F")) {
2820 if (((fcsr >> cc) & 0xf) != 0xf)
2821 target =
pc + offset;
2824 }
else if (op_name.equals_insensitive(
"BC1ANY4T")) {
2826 if (((fcsr >> cc) & 0xf) != 0)
2827 target =
pc + offset;
2870 int element_byte_size,
2872 bool success =
false, branch_hit =
true;
2875 const uint8_t *ptr =
nullptr;
2878 int32_t offset = insn.getOperand(1).getImm();
2886 ptr = (
const uint8_t *)reg_value.
GetBytes();
2890 for (
int i = 0; i < 16 / element_byte_size; i++) {
2891 switch (element_byte_size) {
2893 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2897 if ((*(
const uint16_t *)ptr == 0 && bnz) ||
2898 (*(
const uint16_t *)ptr != 0 && !bnz))
2902 if ((*(
const uint32_t *)ptr == 0 && bnz) ||
2903 (*(
const uint32_t *)ptr != 0 && !bnz))
2907 if ((*(
const uint64_t *)ptr == 0 && bnz) ||
2908 (*(
const uint64_t *)ptr != 0 && !bnz))
2914 ptr = ptr + element_byte_size;
2918 target =
pc + offset;
2939 bool success =
false;
2941 llvm::APInt wr_val = llvm::APInt::getZero(128);
2942 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2943 llvm::APInt zero_value = llvm::APInt::getZero(128);
2947 int32_t offset = insn.getOperand(1).getImm();
2959 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2960 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2961 target =
pc + offset;
2973 bool success =
false;
2975 int32_t imm, address;
2978 uint32_t num_operands = insn.getNumOperands();
2980 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2981 imm = insn.getOperand(num_operands - 1).getImm();
2993 address = address + imm;
3004 bool success =
false;
3006 int32_t address, index_address;
3009 uint32_t num_operands = insn.getNumOperands();
3011 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3013 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3034 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
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)