Lines Matching defs:inst

70 constexpr uint32_t DecodeJImm(uint32_t inst) {
71 return (uint64_t(int64_t(int32_t(inst & 0x80000000)) >> 11)) // imm[20]
72 | (inst & 0xff000) // imm[19:12]
73 | ((inst >> 9) & 0x800) // imm[11]
74 | ((inst >> 20) & 0x7fe); // imm[10:1]
77 constexpr uint32_t DecodeIImm(uint32_t inst) {
78 return int64_t(int32_t(inst)) >> 20; // imm[11:0]
81 constexpr uint32_t DecodeBImm(uint32_t inst) {
82 return (uint64_t(int64_t(int32_t(inst & 0x80000000)) >> 19)) // imm[12]
83 | ((inst & 0x80) << 4) // imm[11]
84 | ((inst >> 20) & 0x7e0) // imm[10:5]
85 | ((inst >> 7) & 0x1e); // imm[4:1]
88 constexpr uint32_t DecodeSImm(uint32_t inst) {
89 return (uint64_t(int64_t(int32_t(inst & 0xFE000000)) >> 20)) // imm[11:5]
90 | ((inst & 0xF80) >> 7); // imm[4:0]
93 constexpr uint32_t DecodeUImm(uint32_t inst) {
94 return SextW(inst & 0xFFFFF000); // imm[31:12]
220 LoadStoreAddr(EmulateInstructionRISCV &emulator, I inst) {
221 return transformOptional(inst.rs1.Read(emulator), [&](uint64_t rs1) {
222 return rs1 + uint64_t(SignExt(inst.imm));
229 Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(E)) {
230 auto addr = LoadStoreAddr(emulator, inst);
235 [&](T t) { return inst.rd.Write(emulator, extend(E(t))); })
241 Store(EmulateInstructionRISCV &emulator, I inst) {
242 auto addr = LoadStoreAddr(emulator, inst);
246 inst.rs2.Read(emulator),
255 AtomicAddr(EmulateInstructionRISCV &emulator, I inst, unsigned int align) {
256 return transformOptional(inst.rs1.Read(emulator),
267 AtomicSwap(EmulateInstructionRISCV &emulator, I inst, int align,
269 auto addr = AtomicAddr(emulator, inst, align);
273 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
277 inst.rd.Write(emulator, extend(tmp));
284 AtomicADD(EmulateInstructionRISCV &emulator, I inst, int align,
286 auto addr = AtomicAddr(emulator, inst, align);
290 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
294 inst.rd.Write(emulator, extend(tmp));
301 AtomicBitOperate(EmulateInstructionRISCV &emulator, I inst, int align,
303 auto addr = AtomicAddr(emulator, inst, align);
307 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
311 inst.rd.Write(emulator, extend(value));
318 AtomicCmp(EmulateInstructionRISCV &emulator, I inst, int align,
320 auto addr = AtomicAddr(emulator, inst, align);
324 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
328 inst.rd.Write(emulator, extend(value));
348 auto inst = emulator.ReadInstructionAt(current_pc);
349 if (!inst || (!std::holds_alternative<LR_W>(inst->decoded) &&
350 !std::holds_alternative<LR_D>(inst->decoded)))
354 inst = emulator.ReadInstructionAt(current_pc += 4);
355 if (!inst || !std::holds_alternative<B>(inst->decoded))
357 auto bne_exit = std::get<B>(inst->decoded);
364 inst = emulator.ReadInstructionAt(current_pc += 4);
365 if (!inst || (!std::holds_alternative<SC_W>(inst->decoded) &&
366 !std::holds_alternative<SC_D>(inst->decoded)))
370 inst = emulator.ReadInstructionAt(current_pc += 4);
371 if (!inst || !std::holds_alternative<B>(inst->decoded))
373 auto bne_start = std::get<B>(inst->decoded);
384 template <typename T> static RISCVInst DecodeUType(uint32_t inst) {
385 return T{Rd{DecodeRD(inst)}, DecodeUImm(inst)};
388 template <typename T> static RISCVInst DecodeJType(uint32_t inst) {
389 return T{Rd{DecodeRD(inst)}, DecodeJImm(inst)};
392 template <typename T> static RISCVInst DecodeIType(uint32_t inst) {
393 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, DecodeIImm(inst)};
396 template <typename T> static RISCVInst DecodeBType(uint32_t inst) {
397 return T{Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}, DecodeBImm(inst),
398 DecodeFunct3(inst)};
401 template <typename T> static RISCVInst DecodeSType(uint32_t inst) {
402 return T{Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}, DecodeSImm(inst)};
405 template <typename T> static RISCVInst DecodeRType(uint32_t inst) {
406 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}};
409 template <typename T> static RISCVInst DecodeRShamtType(uint32_t inst) {
410 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, DecodeRS2(inst)};
413 template <typename T> static RISCVInst DecodeRRS1Type(uint32_t inst) {
414 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}};
417 template <typename T> static RISCVInst DecodeR4Type(uint32_t inst) {
418 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)},
419 Rs{DecodeRS3(inst)}, DecodeRM(inst)};
621 std::optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) {
624 uint16_t try_rvc = uint16_t(inst & 0x0000ffff);
629 bool is_16b = (inst & 0b11) != 0b11;
630 bool is_32b = (inst & 0x1f) != 0x1f;
631 bool is_48b = (inst & 0x3f) != 0x1f;
632 bool is_64b = (inst & 0x7f) != 0x3f;
651 if ((inst & pat.type_mask) == pat.eigen &&
654 log, "EmulateInstructionRISCV::%s: inst(%x at %" PRIx64 ") was decoded to %s",
655 __FUNCTION__, inst, m_addr, pat.name);
656 auto decoded = is_16b ? pat.decode(try_rvc) : pat.decode(inst);
657 return DecodeResult{decoded, inst, is_16b, pat};
660 LLDB_LOGF(log, "EmulateInstructionRISCV::%s: inst(0x%x) was unsupported",
661 __FUNCTION__, inst);
681 bool operator()(LUI inst) { return inst.rd.Write(m_emu, SignExt(inst.imm)); }
682 bool operator()(AUIPC inst) {
685 return inst.rd.Write(m_emu,
686 SignExt(inst.imm) + pc);
690 bool operator()(JAL inst) {
693 return inst.rd.Write(m_emu, pc + delta()) &&
694 m_emu.WritePC(SignExt(inst.imm) + pc);
698 bool operator()(JALR inst) {
699 return transformOptional(zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu)),
702 return inst.rd.Write(m_emu, pc + delta()) &&
703 m_emu.WritePC((SignExt(inst.imm) + rs1) &
708 bool operator()(B inst) {
709 return transformOptional(zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu),
710 inst.rs2.Read(m_emu)),
714 CompareB(rs1, rs2, inst.funct3))
715 return m_emu.WritePC(SignExt(inst.imm) + pc);
720 bool operator()(LB inst) {
721 return Load<LB, uint8_t, int8_t>(m_emu, inst, SextW);
723 bool operator()(LH inst) {
724 return Load<LH, uint16_t, int16_t>(m_emu, inst, SextW);
726 bool operator()(LW inst) {
727 return Load<LW, uint32_t, int32_t>(m_emu, inst, SextW);
729 bool operator()(LBU inst) {
730 return Load<LBU, uint8_t, uint8_t>(m_emu, inst, ZextD);
732 bool operator()(LHU inst) {
733 return Load<LHU, uint16_t, uint16_t>(m_emu, inst, ZextD);
735 bool operator()(SB inst) { return Store<SB, uint8_t>(m_emu, inst); }
736 bool operator()(SH inst) { return Store<SH, uint16_t>(m_emu, inst); }
737 bool operator()(SW inst) { return Store<SW, uint32_t>(m_emu, inst); }
738 bool operator()(ADDI inst) {
739 return transformOptional(inst.rs1.ReadI64(m_emu),
741 return inst.rd.Write(
742 m_emu, rs1 + int64_t(SignExt(inst.imm)));
746 bool operator()(SLTI inst) {
747 return transformOptional(inst.rs1.ReadI64(m_emu),
749 return inst.rd.Write(
750 m_emu, rs1 < int64_t(SignExt(inst.imm)));
754 bool operator()(SLTIU inst) {
755 return transformOptional(inst.rs1.Read(m_emu),
757 return inst.rd.Write(
758 m_emu, rs1 < uint64_t(SignExt(inst.imm)));
762 bool operator()(XORI inst) {
763 return transformOptional(inst.rs1.Read(m_emu),
765 return inst.rd.Write(
766 m_emu, rs1 ^ uint64_t(SignExt(inst.imm)));
770 bool operator()(ORI inst) {
771 return transformOptional(inst.rs1.Read(m_emu),
773 return inst.rd.Write(
774 m_emu, rs1 | uint64_t(SignExt(inst.imm)));
778 bool operator()(ANDI inst) {
779 return transformOptional(inst.rs1.Read(m_emu),
781 return inst.rd.Write(
782 m_emu, rs1 & uint64_t(SignExt(inst.imm)));
786 bool operator()(ADD inst) {
787 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
790 return inst.rd.Write(m_emu, rs1 + rs2);
794 bool operator()(SUB inst) {
795 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
798 return inst.rd.Write(m_emu, rs1 - rs2);
802 bool operator()(SLL inst) {
803 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
806 return inst.rd.Write(m_emu,
811 bool operator()(SLT inst) {
813 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)),
816 return inst.rd.Write(m_emu, rs1 < rs2);
820 bool operator()(SLTU inst) {
821 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
824 return inst.rd.Write(m_emu, rs1 < rs2);
828 bool operator()(XOR inst) {
829 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
832 return inst.rd.Write(m_emu, rs1 ^ rs2);
836 bool operator()(SRL inst) {
837 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
840 return inst.rd.Write(m_emu,
845 bool operator()(SRA inst) {
847 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.Read(m_emu)),
850 return inst.rd.Write(m_emu, rs1 >> (rs2 & 0b111111));
854 bool operator()(OR inst) {
855 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
858 return inst.rd.Write(m_emu, rs1 | rs2);
862 bool operator()(AND inst) {
863 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
866 return inst.rd.Write(m_emu, rs1 & rs2);
870 bool operator()(LWU inst) {
871 return Load<LWU, uint32_t, uint32_t>(m_emu, inst, ZextD);
873 bool operator()(LD inst) {
874 return Load<LD, uint64_t, uint64_t>(m_emu, inst, ZextD);
876 bool operator()(SD inst) { return Store<SD, uint64_t>(m_emu, inst); }
877 bool operator()(SLLI inst) {
878 return transformOptional(inst.rs1.Read(m_emu),
880 return inst.rd.Write(m_emu, rs1 << inst.shamt);
884 bool operator()(SRLI inst) {
885 return transformOptional(inst.rs1.Read(m_emu),
887 return inst.rd.Write(m_emu, rs1 >> inst.shamt);
891 bool operator()(SRAI inst) {
892 return transformOptional(inst.rs1.ReadI64(m_emu),
894 return inst.rd.Write(m_emu, rs1 >> inst.shamt);
898 bool operator()(ADDIW inst) {
899 return transformOptional(inst.rs1.ReadI32(m_emu),
901 return inst.rd.Write(
902 m_emu, SextW(rs1 + SignExt(inst.imm)));
906 bool operator()(SLLIW inst) {
907 return transformOptional(inst.rs1.ReadU32(m_emu),
909 return inst.rd.Write(m_emu,
910 SextW(rs1 << inst.shamt));
914 bool operator()(SRLIW inst) {
915 return transformOptional(inst.rs1.ReadU32(m_emu),
917 return inst.rd.Write(m_emu,
918 SextW(rs1 >> inst.shamt));
922 bool operator()(SRAIW inst) {
923 return transformOptional(inst.rs1.ReadI32(m_emu),
925 return inst.rd.Write(m_emu,
926 SextW(rs1 >> inst.shamt));
930 bool operator()(ADDW inst) {
931 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
934 return inst.rd.Write(m_emu,
939 bool operator()(SUBW inst) {
940 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
943 return inst.rd.Write(m_emu,
948 bool operator()(SLLW inst) {
950 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
953 return inst.rd.Write(m_emu, SextW(rs1 << (rs2 & 0b11111)));
957 bool operator()(SRLW inst) {
959 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
962 return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111)));
966 bool operator()(SRAW inst) {
968 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.Read(m_emu)),
971 return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111)));
976 bool operator()(MUL inst) {
977 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
980 return inst.rd.Write(m_emu, rs1 * rs2);
984 bool operator()(MULH inst) {
986 zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
991 return inst.rd.Write(m_emu,
996 bool operator()(MULHSU inst) {
998 zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
1004 return inst.rd.Write(m_emu,
1009 bool operator()(MULHU inst) {
1011 zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
1016 return inst.rd.Write(m_emu,
1021 bool operator()(DIV inst) {
1023 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)),
1028 return inst.rd.Write(m_emu, UINT64_MAX);
1031 return inst.rd.Write(m_emu, dividend);
1033 return inst.rd.Write(m_emu, dividend / divisor);
1037 bool operator()(DIVU inst) {
1038 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
1043 return inst.rd.Write(m_emu, UINT64_MAX);
1045 return inst.rd.Write(m_emu, dividend / divisor);
1049 bool operator()(REM inst) {
1051 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)),
1056 return inst.rd.Write(m_emu, dividend);
1059 return inst.rd.Write(m_emu, 0);
1061 return inst.rd.Write(m_emu, dividend % divisor);
1065 bool operator()(REMU inst) {
1066 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
1071 return inst.rd.Write(m_emu, dividend);
1073 return inst.rd.Write(m_emu, dividend % divisor);
1077 bool operator()(MULW inst) {
1079 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)),
1082 return inst.rd.Write(m_emu, SextW(rs1 * rs2));
1086 bool operator()(DIVW inst) {
1088 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)),
1093 return inst.rd.Write(m_emu, UINT64_MAX);
1096 return inst.rd.Write(m_emu, SextW(dividend));
1098 return inst.rd.Write(m_emu, SextW(dividend / divisor));
1102 bool operator()(DIVUW inst) {
1104 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
1109 return inst.rd.Write(m_emu, UINT64_MAX);
1111 return inst.rd.Write(m_emu, SextW(dividend / divisor));
1115 bool operator()(REMW inst) {
1117 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)),
1122 return inst.rd.Write(m_emu, SextW(dividend));
1125 return inst.rd.Write(m_emu, 0);
1127 return inst.rd.Write(m_emu, SextW(dividend % divisor));
1131 bool operator()(REMUW inst) {
1133 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
1138 return inst.rd.Write(m_emu, SextW(dividend));
1140 return inst.rd.Write(m_emu, SextW(dividend % divisor));
1153 bool operator()(AMOSWAP_W inst) {
1154 return AtomicSwap<AMOSWAP_W, uint32_t>(m_emu, inst, 4, SextW);
1156 bool operator()(AMOADD_W inst) {
1157 return AtomicADD<AMOADD_W, uint32_t>(m_emu, inst, 4, SextW);
1159 bool operator()(AMOXOR_W inst) {
1161 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { return a ^ b; });
1163 bool operator()(AMOAND_W inst) {
1165 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { return a & b; });
1167 bool operator()(AMOOR_W inst) {
1169 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { return a | b; });
1171 bool operator()(AMOMIN_W inst) {
1173 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) {
1177 bool operator()(AMOMAX_W inst) {
1179 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) {
1183 bool operator()(AMOMINU_W inst) {
1185 m_emu, inst, 4, SextW,
1188 bool operator()(AMOMAXU_W inst) {
1190 m_emu, inst, 4, SextW,
1193 bool operator()(AMOSWAP_D inst) {
1194 return AtomicSwap<AMOSWAP_D, uint64_t>(m_emu, inst, 8, ZextD);
1196 bool operator()(AMOADD_D inst) {
1197 return AtomicADD<AMOADD_D, uint64_t>(m_emu, inst, 8, ZextD);
1199 bool operator()(AMOXOR_D inst) {
1201 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { return a ^ b; });
1203 bool operator()(AMOAND_D inst) {
1205 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { return a & b; });
1207 bool operator()(AMOOR_D inst) {
1209 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { return a | b; });
1211 bool operator()(AMOMIN_D inst) {
1213 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) {
1217 bool operator()(AMOMAX_D inst) {
1219 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) {
1223 bool operator()(AMOMINU_D inst) {
1225 m_emu, inst, 8, ZextD,
1228 bool operator()(AMOMAXU_D inst) {
1230 m_emu, inst, 8, ZextD,
1234 bool F_Load(T inst, const fltSemantics &(*semantics)(),
1236 return transformOptional(inst.rs1.Read(m_emu),
1238 uint64_t addr = rs1 + uint64_t(inst.imm);
1241 return inst.rd.WriteAPFloat(m_emu, f);
1245 bool operator()(FLW inst) { return F_Load(inst, &APFloat::IEEEsingle, 32); }
1246 template <typename T> bool F_Store(T inst, bool isDouble) {
1247 return transformOptional(zipOpt(inst.rs1.Read(m_emu),
1248 inst.rs2.ReadAPFloat(m_emu, isDouble)),
1251 uint64_t addr = rs1 + uint64_t(inst.imm);
1258 bool operator()(FSW inst) { return F_Store(inst, false); }
1266 bool FMA(T inst, bool isDouble, float rs2_sign, float rs3_sign) {
1267 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble),
1268 inst.rs2.ReadAPFloat(m_emu, isDouble),
1269 inst.rs3.ReadAPFloat(m_emu, isDouble)),
1275 return res && inst.rd.WriteAPFloat(m_emu, f);
1279 bool operator()(FMADD_S inst) { return FMA(inst, false, 1.0f, 1.0f); }
1280 bool operator()(FMSUB_S inst) { return FMA(inst, false, 1.0f, -1.0f); }
1281 bool operator()(FNMSUB_S inst) { return FMA(inst, false, -1.0f, 1.0f); }
1282 bool operator()(FNMADD_S inst) { return FMA(inst, false, -1.0f, -1.0f); }
1284 bool F_Op(T inst, bool isDouble,
1287 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble),
1288 inst.rs2.ReadAPFloat(m_emu, isDouble)),
1293 inst.rd.WriteAPFloat(m_emu, rs1);
1298 bool operator()(FADD_S inst) { return F_Op(inst, false, &APFloat::add); }
1299 bool operator()(FSUB_S inst) { return F_Op(inst, false, &APFloat::subtract); }
1300 bool operator()(FMUL_S inst) { return F_Op(inst, false, &APFloat::multiply); }
1301 bool operator()(FDIV_S inst) { return F_Op(inst, false, &APFloat::divide); }
1302 bool operator()(FSQRT_S inst) {
1306 template <typename T> bool F_SignInj(T inst, bool isDouble, bool isNegate) {
1307 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble),
1308 inst.rs2.ReadAPFloat(m_emu, isDouble)),
1314 return inst.rd.WriteAPFloat(m_emu, rs1);
1318 bool operator()(FSGNJ_S inst) { return F_SignInj(inst, false, false); }
1319 bool operator()(FSGNJN_S inst) { return F_SignInj(inst, false, true); }
1320 template <typename T> bool F_SignInjXor(T inst, bool isDouble) {
1321 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble),
1322 inst.rs2.ReadAPFloat(m_emu, isDouble)),
1335 return inst.rd.WriteAPFloat(m_emu, rs1);
1339 bool operator()(FSGNJX_S inst) { return F_SignInjXor(inst, false); }
1341 bool F_MAX_MIN(T inst, bool isDouble,
1344 zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble),
1345 inst.rs2.ReadAPFloat(m_emu, isDouble)),
1356 return inst.rd.WriteAPFloat(m_emu, canonicalNaN);
1358 return inst.rd.WriteAPFloat(m_emu, f(rs1, rs2));
1362 bool operator()(FMIN_S inst) { return F_MAX_MIN(inst, false, minnum); }
1363 bool operator()(FMAX_S inst) { return F_MAX_MIN(inst, false, maxnum); }
1364 bool operator()(FCVT_W_S inst) {
1365 return FCVT_i2f<FCVT_W_S, int32_t, float>(inst, false,
1368 bool operator()(FCVT_WU_S inst) {
1369 return FCVT_i2f<FCVT_WU_S, uint32_t, float>(inst, false,
1372 template <typename T> bool FMV_f2i(T inst, bool isDouble) {
1374 inst.rs1.ReadAPFloat(m_emu, isDouble),
1378 return inst.rd.Write(m_emu, 0x7ff8'0000'0000'0000);
1380 return inst.rd.Write(m_emu, 0x7fc0'0000);
1384 return inst.rd.Write(m_emu, bits);
1386 return inst.rd.Write(m_emu, uint64_t(bits & 0xffff'ffff));
1390 bool operator()(FMV_X_W inst) { return FMV_f2i(inst, false); }
1396 template <typename T> bool F_Compare(T inst, bool isDouble, F_CMP cmp) {
1398 zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble),
1399 inst.rs2.ReadAPFloat(m_emu, isDouble)),
1407 return res && inst.rd.Write(m_emu, 0);
1411 return res && inst.rd.Write(m_emu, 0);
1415 return inst.rd.Write(m_emu,
1418 return inst.rd.Write(m_emu, rs1.compare(rs2) ==
1421 return inst.rd.Write(m_emu, rs1.compare(rs2) !=
1429 bool operator()(FEQ_S inst) { return F_Compare(inst, false, FEQ); }
1430 bool operator()(FLT_S inst) { return F_Compare(inst, false, FLT); }
1431 bool operator()(FLE_S inst) { return F_Compare(inst, false, FLE); }
1432 template <typename T> bool FCLASS(T inst, bool isDouble) {
1433 return transformOptional(inst.rs1.ReadAPFloat(m_emu, isDouble),
1462 return inst.rd.Write(m_emu, result);
1466 bool operator()(FCLASS_S inst) { return FCLASS(inst, false); }
1468 bool FCVT_f2i(T inst, std::optional<E> (Rs::*f)(EmulateInstructionRISCV &emu),
1470 return transformOptional(((&inst.rs1)->*f)(m_emu),
1473 return inst.rd.WriteAPFloat(m_emu, apf);
1477 bool operator()(FCVT_S_W inst) {
1478 return FCVT_f2i(inst, &Rs::ReadI32, APFloat::IEEEsingle());
1480 bool operator()(FCVT_S_WU inst) {
1481 return FCVT_f2i(inst, &Rs::ReadU32, APFloat::IEEEsingle());
1484 bool FMV_i2f(T inst, unsigned int numBits, E (APInt::*f)() const) {
1485 return transformOptional(inst.rs1.Read(m_emu),
1491 return inst.rd.WriteAPFloat(m_emu, apf);
1495 bool operator()(FMV_W_X inst) {
1496 return FMV_i2f(inst, 32, &APInt::bitsToFloat);
1499 bool FCVT_i2f(I inst, bool isDouble, T (APFloat::*f)() const) {
1500 return transformOptional(inst.rs1.ReadAPFloat(m_emu, isDouble),
1503 return inst.rd.Write(m_emu, uint64_t(res));
1507 bool operator()(FCVT_L_S inst) {
1508 return FCVT_i2f<FCVT_L_S, int64_t, float>(inst, false,
1511 bool operator()(FCVT_LU_S inst) {
1512 return FCVT_i2f<FCVT_LU_S, uint64_t, float>(inst, false,
1515 bool operator()(FCVT_S_L inst) {
1516 return FCVT_f2i(inst, &Rs::ReadI64, APFloat::IEEEsingle());
1518 bool operator()(FCVT_S_LU inst) {
1519 return FCVT_f2i(inst, &Rs::Read, APFloat::IEEEsingle());
1521 bool operator()(FLD inst) { return F_Load(inst, &APFloat::IEEEdouble, 64); }
1522 bool operator()(FSD inst) { return F_Store(inst, true); }
1523 bool operator()(FMADD_D inst) { return FMA(inst, true, 1.0f, 1.0f); }
1524 bool operator()(FMSUB_D inst) { return FMA(inst, true, 1.0f, -1.0f); }
1525 bool operator()(FNMSUB_D inst) { return FMA(inst, true, -1.0f, 1.0f); }
1526 bool operator()(FNMADD_D inst) { return FMA(inst, true, -1.0f, -1.0f); }
1527 bool operator()(FADD_D inst) { return F_Op(inst, true, &APFloat::add); }
1528 bool operator()(FSUB_D inst) { return F_Op(inst, true, &APFloat::subtract); }
1529 bool operator()(FMUL_D inst) { return F_Op(inst, true, &APFloat::multiply); }
1530 bool operator()(FDIV_D inst) { return F_Op(inst, true, &APFloat::divide); }
1531 bool operator()(FSQRT_D inst) {
1535 bool operator()(FSGNJ_D inst) { return F_SignInj(inst, true, false); }
1536 bool operator()(FSGNJN_D inst) { return F_SignInj(inst, true, true); }
1537 bool operator()(FSGNJX_D inst) { return F_SignInjXor(inst, true); }
1538 bool operator()(FMIN_D inst) { return F_MAX_MIN(inst, true, minnum); }
1539 bool operator()(FMAX_D inst) { return F_MAX_MIN(inst, true, maxnum); }
1540 bool operator()(FCVT_S_D inst) {
1541 return transformOptional(inst.rs1.ReadAPFloat(m_emu, true),
1545 return inst.rd.WriteAPFloat(m_emu, apf);
1549 bool operator()(FCVT_D_S inst) {
1550 return transformOptional(inst.rs1.ReadAPFloat(m_emu, false),
1554 return inst.rd.WriteAPFloat(m_emu, apf);
1558 bool operator()(FEQ_D inst) { return F_Compare(inst, true, FEQ); }
1559 bool operator()(FLT_D inst) { return F_Compare(inst, true, FLT); }
1560 bool operator()(FLE_D inst) { return F_Compare(inst, true, FLE); }
1561 bool operator()(FCLASS_D inst) { return FCLASS(inst, true); }
1562 bool operator()(FCVT_W_D inst) {
1563 return FCVT_i2f<FCVT_W_D, int32_t, double>(inst, true,
1566 bool operator()(FCVT_WU_D inst) {
1567 return FCVT_i2f<FCVT_WU_D, uint32_t, double>(inst, true,
1570 bool operator()(FCVT_D_W inst) {
1571 return FCVT_f2i(inst, &Rs::ReadI32, APFloat::IEEEdouble());
1573 bool operator()(FCVT_D_WU inst) {
1574 return FCVT_f2i(inst, &Rs::ReadU32, APFloat::IEEEdouble());
1576 bool operator()(FCVT_L_D inst) {
1577 return FCVT_i2f<FCVT_L_D, int64_t, double>(inst, true,
1580 bool operator()(FCVT_LU_D inst) {
1581 return FCVT_i2f<FCVT_LU_D, uint64_t, double>(inst, true,
1584 bool operator()(FMV_X_D inst) { return FMV_f2i(inst, true); }
1585 bool operator()(FCVT_D_L inst) {
1586 return FCVT_f2i(inst, &Rs::ReadI64, APFloat::IEEEdouble());
1588 bool operator()(FCVT_D_LU inst) {
1589 return FCVT_f2i(inst, &Rs::Read, APFloat::IEEEdouble());
1591 bool operator()(FMV_D_X inst) {
1592 return FMV_i2f(inst, 64, &APInt::bitsToDouble);
1594 bool operator()(INVALID inst) { return false; }
1595 bool operator()(RESERVED inst) { return false; }
1596 bool operator()(EBREAK inst) { return false; }
1597 bool operator()(HINT inst) { return true; }
1598 bool operator()(NOP inst) { return true; }
1601 bool EmulateInstructionRISCV::Execute(DecodeResult inst, bool ignore_cond) {
1602 return std::visit(Executor(*this, ignore_cond, inst.is_rvc), inst.decoded);
1632 [&](uint32_t inst) { return Decode(inst); })
1641 auto inst = ReadInstructionAt(*addr);
1642 if (!inst)
1644 m_decoded = *inst;
1645 if (inst->is_rvc)
1646 m_opcode.SetOpcode16(inst->inst, GetByteOrder());
1648 m_opcode.SetOpcode32(inst->inst, GetByteOrder());