Lines Matching refs:inst

70 constexpr uint32_t DecodeJImm(uint32_t inst) {  in DecodeJImm()  argument
71 return (uint64_t(int64_t(int32_t(inst & 0x80000000)) >> 11)) // imm[20] in DecodeJImm()
72 | (inst & 0xff000) // imm[19:12] in DecodeJImm()
73 | ((inst >> 9) & 0x800) // imm[11] in DecodeJImm()
74 | ((inst >> 20) & 0x7fe); // imm[10:1] in DecodeJImm()
77 constexpr uint32_t DecodeIImm(uint32_t inst) { in DecodeIImm() argument
78 return int64_t(int32_t(inst)) >> 20; // imm[11:0] in DecodeIImm()
81 constexpr uint32_t DecodeBImm(uint32_t inst) { in DecodeBImm() argument
82 return (uint64_t(int64_t(int32_t(inst & 0x80000000)) >> 19)) // imm[12] in DecodeBImm()
83 | ((inst & 0x80) << 4) // imm[11] in DecodeBImm()
84 | ((inst >> 20) & 0x7e0) // imm[10:5] in DecodeBImm()
85 | ((inst >> 7) & 0x1e); // imm[4:1] in DecodeBImm()
88 constexpr uint32_t DecodeSImm(uint32_t inst) { in DecodeSImm() argument
89 return (uint64_t(int64_t(int32_t(inst & 0xFE000000)) >> 20)) // imm[11:5] in DecodeSImm()
90 | ((inst & 0xF80) >> 7); // imm[4:0] in DecodeSImm()
93 constexpr uint32_t DecodeUImm(uint32_t inst) { in DecodeUImm() argument
94 return SextW(inst & 0xFFFFF000); // imm[31:12] in DecodeUImm()
220 LoadStoreAddr(EmulateInstructionRISCV &emulator, I inst) { in LoadStoreAddr() argument
221 return transformOptional(inst.rs1.Read(emulator), [&](uint64_t rs1) { in LoadStoreAddr()
222 return rs1 + uint64_t(SignExt(inst.imm)); in LoadStoreAddr()
229 Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(E)) { in Load() argument
230 auto addr = LoadStoreAddr(emulator, inst); in Load()
235 [&](T t) { return inst.rd.Write(emulator, extend(E(t))); }) in Load()
241 Store(EmulateInstructionRISCV &emulator, I inst) { in Store() argument
242 auto addr = LoadStoreAddr(emulator, inst); in Store()
246 inst.rs2.Read(emulator), in Store()
255 AtomicAddr(EmulateInstructionRISCV &emulator, I inst, unsigned int align) { in AtomicAddr() argument
256 return transformOptional(inst.rs1.Read(emulator), in AtomicAddr()
267 AtomicSwap(EmulateInstructionRISCV &emulator, I inst, int align, in AtomicSwap() argument
269 auto addr = AtomicAddr(emulator, inst, align); in AtomicSwap()
273 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)), in AtomicSwap()
277 inst.rd.Write(emulator, extend(tmp)); in AtomicSwap()
284 AtomicADD(EmulateInstructionRISCV &emulator, I inst, int align, in AtomicADD() argument
286 auto addr = AtomicAddr(emulator, inst, align); in AtomicADD()
290 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)), in AtomicADD()
294 inst.rd.Write(emulator, extend(tmp)); in AtomicADD()
301 AtomicBitOperate(EmulateInstructionRISCV &emulator, I inst, int align, in AtomicBitOperate() argument
303 auto addr = AtomicAddr(emulator, inst, align); in AtomicBitOperate()
307 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)), in AtomicBitOperate()
311 inst.rd.Write(emulator, extend(value)); in AtomicBitOperate()
318 AtomicCmp(EmulateInstructionRISCV &emulator, I inst, int align, in AtomicCmp() argument
320 auto addr = AtomicAddr(emulator, inst, align); in AtomicCmp()
324 zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)), in AtomicCmp()
328 inst.rd.Write(emulator, extend(value)); in AtomicCmp()
348 auto inst = emulator.ReadInstructionAt(current_pc); in AtomicSequence() local
349 if (!inst || (!std::holds_alternative<LR_W>(inst->decoded) && in AtomicSequence()
350 !std::holds_alternative<LR_D>(inst->decoded))) in AtomicSequence()
354 inst = emulator.ReadInstructionAt(current_pc += 4); in AtomicSequence()
355 if (!inst || !std::holds_alternative<B>(inst->decoded)) in AtomicSequence()
357 auto bne_exit = std::get<B>(inst->decoded); in AtomicSequence()
364 inst = emulator.ReadInstructionAt(current_pc += 4); in AtomicSequence()
365 if (!inst || (!std::holds_alternative<SC_W>(inst->decoded) && in AtomicSequence()
366 !std::holds_alternative<SC_D>(inst->decoded))) in AtomicSequence()
370 inst = emulator.ReadInstructionAt(current_pc += 4); in AtomicSequence()
371 if (!inst || !std::holds_alternative<B>(inst->decoded)) in AtomicSequence()
373 auto bne_start = std::get<B>(inst->decoded); in AtomicSequence()
384 template <typename T> static RISCVInst DecodeUType(uint32_t inst) { in DecodeUType() argument
385 return T{Rd{DecodeRD(inst)}, DecodeUImm(inst)}; in DecodeUType()
388 template <typename T> static RISCVInst DecodeJType(uint32_t inst) { in DecodeJType() argument
389 return T{Rd{DecodeRD(inst)}, DecodeJImm(inst)}; in DecodeJType()
392 template <typename T> static RISCVInst DecodeIType(uint32_t inst) { in DecodeIType() argument
393 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, DecodeIImm(inst)}; in DecodeIType()
396 template <typename T> static RISCVInst DecodeBType(uint32_t inst) { in DecodeBType() argument
397 return T{Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}, DecodeBImm(inst), in DecodeBType()
398 DecodeFunct3(inst)}; in DecodeBType()
401 template <typename T> static RISCVInst DecodeSType(uint32_t inst) { in DecodeSType() argument
402 return T{Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}, DecodeSImm(inst)}; in DecodeSType()
405 template <typename T> static RISCVInst DecodeRType(uint32_t inst) { in DecodeRType() argument
406 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}}; in DecodeRType()
409 template <typename T> static RISCVInst DecodeRShamtType(uint32_t inst) { in DecodeRShamtType() argument
410 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, DecodeRS2(inst)}; in DecodeRShamtType()
413 template <typename T> static RISCVInst DecodeRRS1Type(uint32_t inst) { in DecodeRRS1Type() argument
414 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}}; in DecodeRRS1Type()
417 template <typename T> static RISCVInst DecodeR4Type(uint32_t inst) { in DecodeR4Type() argument
418 return T{Rd{DecodeRD(inst)}, Rs{DecodeRS1(inst)}, Rs{DecodeRS2(inst)}, in DecodeR4Type()
419 Rs{DecodeRS3(inst)}, DecodeRM(inst)}; in DecodeR4Type()
621 std::optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) { in Decode() argument
624 uint16_t try_rvc = uint16_t(inst & 0x0000ffff); in Decode()
636 if ((inst & pat.type_mask) == pat.eigen && in Decode()
640 __FUNCTION__, inst, m_addr, pat.name); in Decode()
641 auto decoded = is_rvc ? pat.decode(try_rvc) : pat.decode(inst); in Decode()
642 return DecodeResult{decoded, inst, is_rvc, pat}; in Decode()
646 __FUNCTION__, inst); in Decode()
666 bool operator()(LUI inst) { return inst.rd.Write(m_emu, SignExt(inst.imm)); } in operator ()() argument
667 bool operator()(AUIPC inst) { in operator ()() argument
670 return inst.rd.Write(m_emu, in operator ()()
671 SignExt(inst.imm) + pc); in operator ()()
675 bool operator()(JAL inst) { in operator ()() argument
678 return inst.rd.Write(m_emu, pc + delta()) && in operator ()()
679 m_emu.WritePC(SignExt(inst.imm) + pc); in operator ()()
683 bool operator()(JALR inst) { in operator ()() argument
684 return transformOptional(zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu)), in operator ()()
687 return inst.rd.Write(m_emu, pc + delta()) && in operator ()()
688 m_emu.WritePC((SignExt(inst.imm) + rs1) & in operator ()()
693 bool operator()(B inst) { in operator ()() argument
694 return transformOptional(zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu), in operator ()()
695 inst.rs2.Read(m_emu)), in operator ()()
699 CompareB(rs1, rs2, inst.funct3)) in operator ()()
700 return m_emu.WritePC(SignExt(inst.imm) + pc); in operator ()()
705 bool operator()(LB inst) { in operator ()() argument
706 return Load<LB, uint8_t, int8_t>(m_emu, inst, SextW); in operator ()()
708 bool operator()(LH inst) { in operator ()() argument
709 return Load<LH, uint16_t, int16_t>(m_emu, inst, SextW); in operator ()()
711 bool operator()(LW inst) { in operator ()() argument
712 return Load<LW, uint32_t, int32_t>(m_emu, inst, SextW); in operator ()()
714 bool operator()(LBU inst) { in operator ()() argument
715 return Load<LBU, uint8_t, uint8_t>(m_emu, inst, ZextD); in operator ()()
717 bool operator()(LHU inst) { in operator ()() argument
718 return Load<LHU, uint16_t, uint16_t>(m_emu, inst, ZextD); in operator ()()
720 bool operator()(SB inst) { return Store<SB, uint8_t>(m_emu, inst); } in operator ()() argument
721 bool operator()(SH inst) { return Store<SH, uint16_t>(m_emu, inst); } in operator ()() argument
722 bool operator()(SW inst) { return Store<SW, uint32_t>(m_emu, inst); } in operator ()() argument
723 bool operator()(ADDI inst) { in operator ()() argument
724 return transformOptional(inst.rs1.ReadI64(m_emu), in operator ()()
726 return inst.rd.Write( in operator ()()
727 m_emu, rs1 + int64_t(SignExt(inst.imm))); in operator ()()
731 bool operator()(SLTI inst) { in operator ()() argument
732 return transformOptional(inst.rs1.ReadI64(m_emu), in operator ()()
734 return inst.rd.Write( in operator ()()
735 m_emu, rs1 < int64_t(SignExt(inst.imm))); in operator ()()
739 bool operator()(SLTIU inst) { in operator ()() argument
740 return transformOptional(inst.rs1.Read(m_emu), in operator ()()
742 return inst.rd.Write( in operator ()()
743 m_emu, rs1 < uint64_t(SignExt(inst.imm))); in operator ()()
747 bool operator()(XORI inst) { in operator ()() argument
748 return transformOptional(inst.rs1.Read(m_emu), in operator ()()
750 return inst.rd.Write( in operator ()()
751 m_emu, rs1 ^ uint64_t(SignExt(inst.imm))); in operator ()()
755 bool operator()(ORI inst) { in operator ()() argument
756 return transformOptional(inst.rs1.Read(m_emu), in operator ()()
758 return inst.rd.Write( in operator ()()
759 m_emu, rs1 | uint64_t(SignExt(inst.imm))); in operator ()()
763 bool operator()(ANDI inst) { in operator ()() argument
764 return transformOptional(inst.rs1.Read(m_emu), in operator ()()
766 return inst.rd.Write( in operator ()()
767 m_emu, rs1 & uint64_t(SignExt(inst.imm))); in operator ()()
771 bool operator()(ADD inst) { in operator ()() argument
772 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
775 return inst.rd.Write(m_emu, rs1 + rs2); in operator ()()
779 bool operator()(SUB inst) { in operator ()() argument
780 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
783 return inst.rd.Write(m_emu, rs1 - rs2); in operator ()()
787 bool operator()(SLL inst) { in operator ()() argument
788 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
791 return inst.rd.Write(m_emu, in operator ()()
796 bool operator()(SLT inst) { in operator ()() argument
798 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)), in operator ()()
801 return inst.rd.Write(m_emu, rs1 < rs2); in operator ()()
805 bool operator()(SLTU inst) { in operator ()() argument
806 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
809 return inst.rd.Write(m_emu, rs1 < rs2); in operator ()()
813 bool operator()(XOR inst) { in operator ()() argument
814 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
817 return inst.rd.Write(m_emu, rs1 ^ rs2); in operator ()()
821 bool operator()(SRL inst) { in operator ()() argument
822 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
825 return inst.rd.Write(m_emu, in operator ()()
830 bool operator()(SRA inst) { in operator ()() argument
832 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.Read(m_emu)), in operator ()()
835 return inst.rd.Write(m_emu, rs1 >> (rs2 & 0b111111)); in operator ()()
839 bool operator()(OR inst) { in operator ()() argument
840 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
843 return inst.rd.Write(m_emu, rs1 | rs2); in operator ()()
847 bool operator()(AND inst) { in operator ()() argument
848 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
851 return inst.rd.Write(m_emu, rs1 & rs2); in operator ()()
855 bool operator()(LWU inst) { in operator ()() argument
856 return Load<LWU, uint32_t, uint32_t>(m_emu, inst, ZextD); in operator ()()
858 bool operator()(LD inst) { in operator ()() argument
859 return Load<LD, uint64_t, uint64_t>(m_emu, inst, ZextD); in operator ()()
861 bool operator()(SD inst) { return Store<SD, uint64_t>(m_emu, inst); } in operator ()() argument
862 bool operator()(SLLI inst) { in operator ()() argument
863 return transformOptional(inst.rs1.Read(m_emu), in operator ()()
865 return inst.rd.Write(m_emu, rs1 << inst.shamt); in operator ()()
869 bool operator()(SRLI inst) { in operator ()() argument
870 return transformOptional(inst.rs1.Read(m_emu), in operator ()()
872 return inst.rd.Write(m_emu, rs1 >> inst.shamt); in operator ()()
876 bool operator()(SRAI inst) { in operator ()() argument
877 return transformOptional(inst.rs1.ReadI64(m_emu), in operator ()()
879 return inst.rd.Write(m_emu, rs1 >> inst.shamt); in operator ()()
883 bool operator()(ADDIW inst) { in operator ()() argument
884 return transformOptional(inst.rs1.ReadI32(m_emu), in operator ()()
886 return inst.rd.Write( in operator ()()
887 m_emu, SextW(rs1 + SignExt(inst.imm))); in operator ()()
891 bool operator()(SLLIW inst) { in operator ()() argument
892 return transformOptional(inst.rs1.ReadU32(m_emu), in operator ()()
894 return inst.rd.Write(m_emu, in operator ()()
895 SextW(rs1 << inst.shamt)); in operator ()()
899 bool operator()(SRLIW inst) { in operator ()() argument
900 return transformOptional(inst.rs1.ReadU32(m_emu), in operator ()()
902 return inst.rd.Write(m_emu, in operator ()()
903 SextW(rs1 >> inst.shamt)); in operator ()()
907 bool operator()(SRAIW inst) { in operator ()() argument
908 return transformOptional(inst.rs1.ReadI32(m_emu), in operator ()()
910 return inst.rd.Write(m_emu, in operator ()()
911 SextW(rs1 >> inst.shamt)); in operator ()()
915 bool operator()(ADDW inst) { in operator ()() argument
916 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
919 return inst.rd.Write(m_emu, in operator ()()
924 bool operator()(SUBW inst) { in operator ()() argument
925 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
928 return inst.rd.Write(m_emu, in operator ()()
933 bool operator()(SLLW inst) { in operator ()() argument
935 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)), in operator ()()
938 return inst.rd.Write(m_emu, SextW(rs1 << (rs2 & 0b11111))); in operator ()()
942 bool operator()(SRLW inst) { in operator ()() argument
944 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)), in operator ()()
947 return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111))); in operator ()()
951 bool operator()(SRAW inst) { in operator ()() argument
953 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.Read(m_emu)), in operator ()()
956 return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111))); in operator ()()
961 bool operator()(MUL inst) { in operator ()() argument
962 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
965 return inst.rd.Write(m_emu, rs1 * rs2); in operator ()()
969 bool operator()(MULH inst) { in operator ()() argument
971 zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
976 return inst.rd.Write(m_emu, in operator ()()
981 bool operator()(MULHSU inst) { in operator ()() argument
983 zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
989 return inst.rd.Write(m_emu, in operator ()()
994 bool operator()(MULHU inst) { in operator ()() argument
996 zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
1001 return inst.rd.Write(m_emu, in operator ()()
1006 bool operator()(DIV inst) { in operator ()() argument
1008 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)), in operator ()()
1013 return inst.rd.Write(m_emu, UINT64_MAX); in operator ()()
1016 return inst.rd.Write(m_emu, dividend); in operator ()()
1018 return inst.rd.Write(m_emu, dividend / divisor); in operator ()()
1022 bool operator()(DIVU inst) { in operator ()() argument
1023 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
1028 return inst.rd.Write(m_emu, UINT64_MAX); in operator ()()
1030 return inst.rd.Write(m_emu, dividend / divisor); in operator ()()
1034 bool operator()(REM inst) { in operator ()() argument
1036 zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)), in operator ()()
1041 return inst.rd.Write(m_emu, dividend); in operator ()()
1044 return inst.rd.Write(m_emu, 0); in operator ()()
1046 return inst.rd.Write(m_emu, dividend % divisor); in operator ()()
1050 bool operator()(REMU inst) { in operator ()() argument
1051 return transformOptional(zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)), in operator ()()
1056 return inst.rd.Write(m_emu, dividend); in operator ()()
1058 return inst.rd.Write(m_emu, dividend % divisor); in operator ()()
1062 bool operator()(MULW inst) { in operator ()() argument
1064 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)), in operator ()()
1067 return inst.rd.Write(m_emu, SextW(rs1 * rs2)); in operator ()()
1071 bool operator()(DIVW inst) { in operator ()() argument
1073 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)), in operator ()()
1078 return inst.rd.Write(m_emu, UINT64_MAX); in operator ()()
1081 return inst.rd.Write(m_emu, SextW(dividend)); in operator ()()
1083 return inst.rd.Write(m_emu, SextW(dividend / divisor)); in operator ()()
1087 bool operator()(DIVUW inst) { in operator ()() argument
1089 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)), in operator ()()
1094 return inst.rd.Write(m_emu, UINT64_MAX); in operator ()()
1096 return inst.rd.Write(m_emu, SextW(dividend / divisor)); in operator ()()
1100 bool operator()(REMW inst) { in operator ()() argument
1102 zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)), in operator ()()
1107 return inst.rd.Write(m_emu, SextW(dividend)); in operator ()()
1110 return inst.rd.Write(m_emu, 0); in operator ()()
1112 return inst.rd.Write(m_emu, SextW(dividend % divisor)); in operator ()()
1116 bool operator()(REMUW inst) { in operator ()() argument
1118 zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)), in operator ()()
1123 return inst.rd.Write(m_emu, SextW(dividend)); in operator ()()
1125 return inst.rd.Write(m_emu, SextW(dividend % divisor)); in operator ()()
1138 bool operator()(AMOSWAP_W inst) { in operator ()() argument
1139 return AtomicSwap<AMOSWAP_W, uint32_t>(m_emu, inst, 4, SextW); in operator ()()
1141 bool operator()(AMOADD_W inst) { in operator ()() argument
1142 return AtomicADD<AMOADD_W, uint32_t>(m_emu, inst, 4, SextW); in operator ()()
1144 bool operator()(AMOXOR_W inst) { in operator ()() argument
1146 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { return a ^ b; }); in operator ()()
1148 bool operator()(AMOAND_W inst) { in operator ()() argument
1150 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { return a & b; }); in operator ()()
1152 bool operator()(AMOOR_W inst) { in operator ()() argument
1154 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { return a | b; }); in operator ()()
1156 bool operator()(AMOMIN_W inst) { in operator ()() argument
1158 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { in operator ()()
1162 bool operator()(AMOMAX_W inst) { in operator ()() argument
1164 m_emu, inst, 4, SextW, [](uint32_t a, uint32_t b) { in operator ()()
1168 bool operator()(AMOMINU_W inst) { in operator ()() argument
1170 m_emu, inst, 4, SextW, in operator ()()
1173 bool operator()(AMOMAXU_W inst) { in operator ()() argument
1175 m_emu, inst, 4, SextW, in operator ()()
1178 bool operator()(AMOSWAP_D inst) { in operator ()() argument
1179 return AtomicSwap<AMOSWAP_D, uint64_t>(m_emu, inst, 8, ZextD); in operator ()()
1181 bool operator()(AMOADD_D inst) { in operator ()() argument
1182 return AtomicADD<AMOADD_D, uint64_t>(m_emu, inst, 8, ZextD); in operator ()()
1184 bool operator()(AMOXOR_D inst) { in operator ()() argument
1186 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { return a ^ b; }); in operator ()()
1188 bool operator()(AMOAND_D inst) { in operator ()() argument
1190 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { return a & b; }); in operator ()()
1192 bool operator()(AMOOR_D inst) { in operator ()() argument
1194 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { return a | b; }); in operator ()()
1196 bool operator()(AMOMIN_D inst) { in operator ()() argument
1198 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { in operator ()()
1202 bool operator()(AMOMAX_D inst) { in operator ()() argument
1204 m_emu, inst, 8, ZextD, [](uint64_t a, uint64_t b) { in operator ()()
1208 bool operator()(AMOMINU_D inst) { in operator ()() argument
1210 m_emu, inst, 8, ZextD, in operator ()()
1213 bool operator()(AMOMAXU_D inst) { in operator ()() argument
1215 m_emu, inst, 8, ZextD, in operator ()()
1219 bool F_Load(T inst, const fltSemantics &(*semantics)(), in F_Load() argument
1221 return transformOptional(inst.rs1.Read(m_emu), in F_Load()
1223 uint64_t addr = rs1 + uint64_t(inst.imm); in F_Load()
1226 return inst.rd.WriteAPFloat(m_emu, f); in F_Load()
1230 bool operator()(FLW inst) { return F_Load(inst, &APFloat::IEEEsingle, 32); } in operator ()() argument
1231 template <typename T> bool F_Store(T inst, bool isDouble) { in F_Store() argument
1232 return transformOptional(zipOpt(inst.rs1.Read(m_emu), in F_Store()
1233 inst.rs2.ReadAPFloat(m_emu, isDouble)), in F_Store()
1236 uint64_t addr = rs1 + uint64_t(inst.imm); in F_Store()
1243 bool operator()(FSW inst) { return F_Store(inst, false); } in operator ()() argument
1251 bool FMA(T inst, bool isDouble, float rs2_sign, float rs3_sign) { in FMA() argument
1252 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble), in FMA()
1253 inst.rs2.ReadAPFloat(m_emu, isDouble), in FMA()
1254 inst.rs3.ReadAPFloat(m_emu, isDouble)), in FMA()
1260 return res && inst.rd.WriteAPFloat(m_emu, f); in FMA()
1264 bool operator()(FMADD_S inst) { return FMA(inst, false, 1.0f, 1.0f); } in operator ()() argument
1265 bool operator()(FMSUB_S inst) { return FMA(inst, false, 1.0f, -1.0f); } in operator ()() argument
1266 bool operator()(FNMSUB_S inst) { return FMA(inst, false, -1.0f, 1.0f); } in operator ()() argument
1267 bool operator()(FNMADD_S inst) { return FMA(inst, false, -1.0f, -1.0f); } in operator ()() argument
1269 bool F_Op(T inst, bool isDouble, in F_Op() argument
1272 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble), in F_Op()
1273 inst.rs2.ReadAPFloat(m_emu, isDouble)), in F_Op()
1278 inst.rd.WriteAPFloat(m_emu, rs1); in F_Op()
1283 bool operator()(FADD_S inst) { return F_Op(inst, false, &APFloat::add); } in operator ()() argument
1284 bool operator()(FSUB_S inst) { return F_Op(inst, false, &APFloat::subtract); } in operator ()() argument
1285 bool operator()(FMUL_S inst) { return F_Op(inst, false, &APFloat::multiply); } in operator ()() argument
1286 bool operator()(FDIV_S inst) { return F_Op(inst, false, &APFloat::divide); } in operator ()() argument
1287 bool operator()(FSQRT_S inst) { in operator ()() argument
1291 template <typename T> bool F_SignInj(T inst, bool isDouble, bool isNegate) { in F_SignInj() argument
1292 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble), in F_SignInj()
1293 inst.rs2.ReadAPFloat(m_emu, isDouble)), in F_SignInj()
1299 return inst.rd.WriteAPFloat(m_emu, rs1); in F_SignInj()
1303 bool operator()(FSGNJ_S inst) { return F_SignInj(inst, false, false); } in operator ()() argument
1304 bool operator()(FSGNJN_S inst) { return F_SignInj(inst, false, true); } in operator ()() argument
1305 template <typename T> bool F_SignInjXor(T inst, bool isDouble) { in F_SignInjXor() argument
1306 return transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble), in F_SignInjXor()
1307 inst.rs2.ReadAPFloat(m_emu, isDouble)), in F_SignInjXor()
1320 return inst.rd.WriteAPFloat(m_emu, rs1); in F_SignInjXor()
1324 bool operator()(FSGNJX_S inst) { return F_SignInjXor(inst, false); } in operator ()() argument
1326 bool F_MAX_MIN(T inst, bool isDouble, in F_MAX_MIN() argument
1329 zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble), in F_MAX_MIN()
1330 inst.rs2.ReadAPFloat(m_emu, isDouble)), in F_MAX_MIN()
1341 return inst.rd.WriteAPFloat(m_emu, canonicalNaN); in F_MAX_MIN()
1343 return inst.rd.WriteAPFloat(m_emu, f(rs1, rs2)); in F_MAX_MIN()
1347 bool operator()(FMIN_S inst) { return F_MAX_MIN(inst, false, minnum); } in operator ()() argument
1348 bool operator()(FMAX_S inst) { return F_MAX_MIN(inst, false, maxnum); } in operator ()() argument
1349 bool operator()(FCVT_W_S inst) { in operator ()() argument
1350 return FCVT_i2f<FCVT_W_S, int32_t, float>(inst, false, in operator ()()
1353 bool operator()(FCVT_WU_S inst) { in operator ()() argument
1354 return FCVT_i2f<FCVT_WU_S, uint32_t, float>(inst, false, in operator ()()
1357 template <typename T> bool FMV_f2i(T inst, bool isDouble) { in FMV_f2i() argument
1359 inst.rs1.ReadAPFloat(m_emu, isDouble), in FMV_f2i()
1363 return inst.rd.Write(m_emu, 0x7ff8'0000'0000'0000); in FMV_f2i()
1365 return inst.rd.Write(m_emu, 0x7fc0'0000); in FMV_f2i()
1369 return inst.rd.Write(m_emu, bits); in FMV_f2i()
1371 return inst.rd.Write(m_emu, uint64_t(bits & 0xffff'ffff)); in FMV_f2i()
1375 bool operator()(FMV_X_W inst) { return FMV_f2i(inst, false); } in operator ()() argument
1381 template <typename T> bool F_Compare(T inst, bool isDouble, F_CMP cmp) { in F_Compare() argument
1383 zipOpt(inst.rs1.ReadAPFloat(m_emu, isDouble), in F_Compare()
1384 inst.rs2.ReadAPFloat(m_emu, isDouble)), in F_Compare()
1392 return res && inst.rd.Write(m_emu, 0); in F_Compare()
1396 return res && inst.rd.Write(m_emu, 0); in F_Compare()
1400 return inst.rd.Write(m_emu, in F_Compare()
1403 return inst.rd.Write(m_emu, rs1.compare(rs2) == in F_Compare()
1406 return inst.rd.Write(m_emu, rs1.compare(rs2) != in F_Compare()
1414 bool operator()(FEQ_S inst) { return F_Compare(inst, false, FEQ); } in operator ()() argument
1415 bool operator()(FLT_S inst) { return F_Compare(inst, false, FLT); } in operator ()() argument
1416 bool operator()(FLE_S inst) { return F_Compare(inst, false, FLE); } in operator ()() argument
1417 template <typename T> bool FCLASS(T inst, bool isDouble) { in FCLASS() argument
1418 return transformOptional(inst.rs1.ReadAPFloat(m_emu, isDouble), in FCLASS()
1447 return inst.rd.Write(m_emu, result); in FCLASS()
1451 bool operator()(FCLASS_S inst) { return FCLASS(inst, false); } in operator ()() argument
1453 bool FCVT_f2i(T inst, std::optional<E> (Rs::*f)(EmulateInstructionRISCV &emu), in FCVT_f2i() argument
1455 return transformOptional(((&inst.rs1)->*f)(m_emu), in FCVT_f2i()
1458 return inst.rd.WriteAPFloat(m_emu, apf); in FCVT_f2i()
1462 bool operator()(FCVT_S_W inst) { in operator ()() argument
1463 return FCVT_f2i(inst, &Rs::ReadI32, APFloat::IEEEsingle()); in operator ()()
1465 bool operator()(FCVT_S_WU inst) { in operator ()() argument
1466 return FCVT_f2i(inst, &Rs::ReadU32, APFloat::IEEEsingle()); in operator ()()
1469 bool FMV_i2f(T inst, unsigned int numBits, E (APInt::*f)() const) { in FMV_i2f() argument
1470 return transformOptional(inst.rs1.Read(m_emu), in FMV_i2f()
1476 return inst.rd.WriteAPFloat(m_emu, apf); in FMV_i2f()
1480 bool operator()(FMV_W_X inst) { in operator ()() argument
1481 return FMV_i2f(inst, 32, &APInt::bitsToFloat); in operator ()()
1484 bool FCVT_i2f(I inst, bool isDouble, T (APFloat::*f)() const) { in FCVT_i2f() argument
1485 return transformOptional(inst.rs1.ReadAPFloat(m_emu, isDouble), in FCVT_i2f()
1488 return inst.rd.Write(m_emu, uint64_t(res)); in FCVT_i2f()
1492 bool operator()(FCVT_L_S inst) { in operator ()() argument
1493 return FCVT_i2f<FCVT_L_S, int64_t, float>(inst, false, in operator ()()
1496 bool operator()(FCVT_LU_S inst) { in operator ()() argument
1497 return FCVT_i2f<FCVT_LU_S, uint64_t, float>(inst, false, in operator ()()
1500 bool operator()(FCVT_S_L inst) { in operator ()() argument
1501 return FCVT_f2i(inst, &Rs::ReadI64, APFloat::IEEEsingle()); in operator ()()
1503 bool operator()(FCVT_S_LU inst) { in operator ()() argument
1504 return FCVT_f2i(inst, &Rs::Read, APFloat::IEEEsingle()); in operator ()()
1506 bool operator()(FLD inst) { return F_Load(inst, &APFloat::IEEEdouble, 64); } in operator ()() argument
1507 bool operator()(FSD inst) { return F_Store(inst, true); } in operator ()() argument
1508 bool operator()(FMADD_D inst) { return FMA(inst, true, 1.0f, 1.0f); } in operator ()() argument
1509 bool operator()(FMSUB_D inst) { return FMA(inst, true, 1.0f, -1.0f); } in operator ()() argument
1510 bool operator()(FNMSUB_D inst) { return FMA(inst, true, -1.0f, 1.0f); } in operator ()() argument
1511 bool operator()(FNMADD_D inst) { return FMA(inst, true, -1.0f, -1.0f); } in operator ()() argument
1512 bool operator()(FADD_D inst) { return F_Op(inst, true, &APFloat::add); } in operator ()() argument
1513 bool operator()(FSUB_D inst) { return F_Op(inst, true, &APFloat::subtract); } in operator ()() argument
1514 bool operator()(FMUL_D inst) { return F_Op(inst, true, &APFloat::multiply); } in operator ()() argument
1515 bool operator()(FDIV_D inst) { return F_Op(inst, true, &APFloat::divide); } in operator ()() argument
1516 bool operator()(FSQRT_D inst) { in operator ()() argument
1520 bool operator()(FSGNJ_D inst) { return F_SignInj(inst, true, false); } in operator ()() argument
1521 bool operator()(FSGNJN_D inst) { return F_SignInj(inst, true, true); } in operator ()() argument
1522 bool operator()(FSGNJX_D inst) { return F_SignInjXor(inst, true); } in operator ()() argument
1523 bool operator()(FMIN_D inst) { return F_MAX_MIN(inst, true, minnum); } in operator ()() argument
1524 bool operator()(FMAX_D inst) { return F_MAX_MIN(inst, true, maxnum); } in operator ()() argument
1525 bool operator()(FCVT_S_D inst) { in operator ()() argument
1526 return transformOptional(inst.rs1.ReadAPFloat(m_emu, true), in operator ()()
1530 return inst.rd.WriteAPFloat(m_emu, apf); in operator ()()
1534 bool operator()(FCVT_D_S inst) { in operator ()() argument
1535 return transformOptional(inst.rs1.ReadAPFloat(m_emu, false), in operator ()()
1539 return inst.rd.WriteAPFloat(m_emu, apf); in operator ()()
1543 bool operator()(FEQ_D inst) { return F_Compare(inst, true, FEQ); } in operator ()() argument
1544 bool operator()(FLT_D inst) { return F_Compare(inst, true, FLT); } in operator ()() argument
1545 bool operator()(FLE_D inst) { return F_Compare(inst, true, FLE); } in operator ()() argument
1546 bool operator()(FCLASS_D inst) { return FCLASS(inst, true); } in operator ()() argument
1547 bool operator()(FCVT_W_D inst) { in operator ()() argument
1548 return FCVT_i2f<FCVT_W_D, int32_t, double>(inst, true, in operator ()()
1551 bool operator()(FCVT_WU_D inst) { in operator ()() argument
1552 return FCVT_i2f<FCVT_WU_D, uint32_t, double>(inst, true, in operator ()()
1555 bool operator()(FCVT_D_W inst) { in operator ()() argument
1556 return FCVT_f2i(inst, &Rs::ReadI32, APFloat::IEEEdouble()); in operator ()()
1558 bool operator()(FCVT_D_WU inst) { in operator ()() argument
1559 return FCVT_f2i(inst, &Rs::ReadU32, APFloat::IEEEdouble()); in operator ()()
1561 bool operator()(FCVT_L_D inst) { in operator ()() argument
1562 return FCVT_i2f<FCVT_L_D, int64_t, double>(inst, true, in operator ()()
1565 bool operator()(FCVT_LU_D inst) { in operator ()() argument
1566 return FCVT_i2f<FCVT_LU_D, uint64_t, double>(inst, true, in operator ()()
1569 bool operator()(FMV_X_D inst) { return FMV_f2i(inst, true); } in operator ()() argument
1570 bool operator()(FCVT_D_L inst) { in operator ()() argument
1571 return FCVT_f2i(inst, &Rs::ReadI64, APFloat::IEEEdouble()); in operator ()()
1573 bool operator()(FCVT_D_LU inst) { in operator ()() argument
1574 return FCVT_f2i(inst, &Rs::Read, APFloat::IEEEdouble()); in operator ()()
1576 bool operator()(FMV_D_X inst) { in operator ()() argument
1577 return FMV_i2f(inst, 64, &APInt::bitsToDouble); in operator ()()
1579 bool operator()(INVALID inst) { return false; } in operator ()() argument
1580 bool operator()(RESERVED inst) { return false; } in operator ()() argument
1581 bool operator()(EBREAK inst) { return false; } in operator ()() argument
1582 bool operator()(HINT inst) { return true; } in operator ()() argument
1583 bool operator()(NOP inst) { return true; } in operator ()() argument
1586 bool EmulateInstructionRISCV::Execute(DecodeResult inst, bool ignore_cond) { in Execute() argument
1587 return std::visit(Executor(*this, ignore_cond, inst.is_rvc), inst.decoded); in Execute()
1617 [&](uint32_t inst) { return Decode(inst); }) in ReadInstructionAt() argument
1626 auto inst = ReadInstructionAt(*addr); in ReadInstruction() local
1627 if (!inst) in ReadInstruction()
1629 m_decoded = *inst; in ReadInstruction()
1630 if (inst->is_rvc) in ReadInstruction()
1631 m_opcode.SetOpcode16(inst->inst, GetByteOrder()); in ReadInstruction()
1633 m_opcode.SetOpcode32(inst->inst, GetByteOrder()); in ReadInstruction()