mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-09 21:19:38 +00:00
8347794: RISC-V: Add Zfhmin - Float cleanup
Reviewed-by: fyang, mli
This commit is contained in:
parent
9b98cc0ba7
commit
fb43849227
@ -552,24 +552,6 @@ public:
|
||||
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct3) \
|
||||
void NAME(FloatRegister Rd, Register Rs, const int32_t offset) { \
|
||||
guarantee(is_simm12(offset), "offset is invalid."); \
|
||||
unsigned insn = 0; \
|
||||
uint32_t val = offset & 0xfff; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, funct3); \
|
||||
patch_reg((address)&insn, 15, Rs); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch((address)&insn, 31, 20, val); \
|
||||
emit(insn); \
|
||||
}
|
||||
|
||||
INSN(flw, 0b0000111, 0b010);
|
||||
INSN(_fld, 0b0000111, 0b011);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct3) \
|
||||
void NAME(Register Rs1, Register Rs2, const int64_t offset) { \
|
||||
guarantee(is_simm13(offset) && ((offset % 2) == 0), "offset is invalid."); \
|
||||
@ -813,26 +795,6 @@ enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
INSN(sc_d, 0b0101111, 0b011, 0b00011);
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct5, funct7) \
|
||||
void NAME(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, rm); \
|
||||
patch((address)&insn, 24, 20, funct5); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn); \
|
||||
}
|
||||
|
||||
INSN(fsqrt_s, 0b1010011, 0b00000, 0b0101100);
|
||||
INSN(fsqrt_d, 0b1010011, 0b00000, 0b0101101);
|
||||
INSN(fcvt_s_h, 0b1010011, 0b00010, 0b0100000);
|
||||
INSN(fcvt_h_s, 0b1010011, 0b00000, 0b0100010);
|
||||
INSN(fcvt_s_d, 0b1010011, 0b00001, 0b0100000);
|
||||
INSN(fcvt_d_s, 0b1010011, 0b00000, 0b0100001);
|
||||
#undef INSN
|
||||
|
||||
// Immediate Instruction
|
||||
#define INSN(NAME, op, funct3) \
|
||||
void NAME(Register Rd, Register Rs1, int64_t imm) { \
|
||||
@ -928,209 +890,408 @@ enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Rigster Instruction
|
||||
#define INSN(NAME, op, funct2) \
|
||||
void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, rm); \
|
||||
patch((address)&insn, 26, 25, funct2); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
patch_reg((address)&insn, 20, Rs2); \
|
||||
patch_reg((address)&insn, 27, Rs3); \
|
||||
emit(insn); \
|
||||
// ==========================
|
||||
// Floating Point Instructions
|
||||
// ==========================
|
||||
static constexpr uint32_t OP_FP_MAJOR = 0b1010011;
|
||||
|
||||
enum FmtPrecision : uint8_t {
|
||||
S_32_sp = 0b00,
|
||||
D_64_dp = 0b01,
|
||||
H_16_hp = 0b10,
|
||||
Q_128_qp = 0b11
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(uint8_t Rd, uint8_t Rs1, uint8_t Rs2, RoundingMode rm) {
|
||||
assert(Fmt != H_16_hp || UseZfh || UseZfhmin, "No half precision enabled");
|
||||
assert_cond(Fmt != Q_128_qp);
|
||||
guarantee(is_uimm3(rm), "Rounding mode is out of validity");
|
||||
guarantee(is_uimm2(Fmt), "FMT is out of validity");
|
||||
guarantee(is_uimm5(funct5), "Funct5 is out of validity");
|
||||
uint32_t insn = 0;
|
||||
patch((address)&insn, 6, 0, OP_FP_MAJOR);
|
||||
patch((address)&insn, 11, 7, Rd);
|
||||
patch((address)&insn, 14, 12, rm);
|
||||
patch((address)&insn, 19, 15, Rs1);
|
||||
patch((address)&insn, 24, 20, Rs2);
|
||||
patch((address)&insn, 26, 25, Fmt);
|
||||
patch((address)&insn, 31, 27, funct5);
|
||||
emit(insn);
|
||||
}
|
||||
|
||||
INSN(fmadd_s, 0b1000011, 0b00);
|
||||
INSN(fmsub_s, 0b1000111, 0b00);
|
||||
INSN(fnmsub_s, 0b1001011, 0b00);
|
||||
INSN(fnmadd_s, 0b1001111, 0b00);
|
||||
INSN(fmadd_d, 0b1000011, 0b01);
|
||||
INSN(fmsub_d, 0b1000111, 0b01);
|
||||
INSN(fnmsub_d, 0b1001011, 0b01);
|
||||
INSN(fnmadd_d, 0b1001111, 0b01);
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Rigster Instruction
|
||||
#define INSN(NAME, op, funct3, funct7) \
|
||||
void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, funct3); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
patch_reg((address)&insn, 20, Rs2); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm) {
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), rm);
|
||||
}
|
||||
|
||||
INSN(fsgnj_s, 0b1010011, 0b000, 0b0010000);
|
||||
INSN(fsgnjn_s, 0b1010011, 0b001, 0b0010000);
|
||||
INSN(fsgnjx_s, 0b1010011, 0b010, 0b0010000);
|
||||
INSN(fmin_s, 0b1010011, 0b000, 0b0010100);
|
||||
INSN(fmax_s, 0b1010011, 0b001, 0b0010100);
|
||||
INSN(fsgnj_d, 0b1010011, 0b000, 0b0010001);
|
||||
INSN(fsgnjn_d, 0b1010011, 0b001, 0b0010001);
|
||||
INSN(fsgnjx_d, 0b1010011, 0b010, 0b0010001);
|
||||
INSN(fmin_d, 0b1010011, 0b000, 0b0010101);
|
||||
INSN(fmax_d, 0b1010011, 0b001, 0b0010101);
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Rigster Arith Instruction
|
||||
#define INSN(NAME, op, funct3, funct7) \
|
||||
void NAME(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, funct3); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
patch_reg((address)&insn, 20, Rs2); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, int8_t rm) {
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), (RoundingMode)rm);
|
||||
}
|
||||
|
||||
INSN(feq_s, 0b1010011, 0b010, 0b1010000);
|
||||
INSN(flt_s, 0b1010011, 0b001, 0b1010000);
|
||||
INSN(fle_s, 0b1010011, 0b000, 0b1010000);
|
||||
INSN(feq_d, 0b1010011, 0b010, 0b1010001);
|
||||
INSN(fle_d, 0b1010011, 0b000, 0b1010001);
|
||||
INSN(flt_d, 0b1010011, 0b001, 0b1010001);
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Arith Instruction
|
||||
#define INSN(NAME, op, funct7) \
|
||||
void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, rm); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
patch_reg((address)&insn, 20, Rs2); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(Register Rd, FloatRegister Rs1, FloatRegister Rs2, int8_t rm) {
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), (RoundingMode)rm);
|
||||
}
|
||||
|
||||
INSN(fadd_s, 0b1010011, 0b0000000);
|
||||
INSN(fsub_s, 0b1010011, 0b0000100);
|
||||
INSN(fmul_s, 0b1010011, 0b0001000);
|
||||
INSN(fdiv_s, 0b1010011, 0b0001100);
|
||||
INSN(fadd_d, 0b1010011, 0b0000001);
|
||||
INSN(fsub_d, 0b1010011, 0b0000101);
|
||||
INSN(fmul_d, 0b1010011, 0b0001001);
|
||||
INSN(fdiv_d, 0b1010011, 0b0001101);
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Whole Float and Double Conversion Instruction
|
||||
#define INSN(NAME, op, funct5, funct7) \
|
||||
void NAME(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, rm); \
|
||||
patch((address)&insn, 24, 20, funct5); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(FloatRegister Rd, FloatRegister Rs1, int8_t Rs2, int8_t rm) {
|
||||
guarantee(is_uimm5(Rs2), "Rs2 is out of validity");
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm);
|
||||
}
|
||||
|
||||
INSN(fcvt_s_w, 0b1010011, 0b00000, 0b1101000);
|
||||
INSN(fcvt_s_wu, 0b1010011, 0b00001, 0b1101000);
|
||||
INSN(fcvt_s_l, 0b1010011, 0b00010, 0b1101000);
|
||||
INSN(fcvt_s_lu, 0b1010011, 0b00011, 0b1101000);
|
||||
INSN(fcvt_d_w, 0b1010011, 0b00000, 0b1101001);
|
||||
INSN(fcvt_d_wu, 0b1010011, 0b00001, 0b1101001);
|
||||
INSN(fcvt_d_l, 0b1010011, 0b00010, 0b1101001);
|
||||
INSN(fcvt_d_lu, 0b1010011, 0b00011, 0b1101001);
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Conversion Instruction
|
||||
#define INSN(NAME, op, funct5, funct7) \
|
||||
void NAME(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, rm); \
|
||||
patch((address)&insn, 24, 20, funct5); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(FloatRegister Rd, Register Rs1, FloatRegister Rs2, RoundingMode rm) {
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), rm);
|
||||
}
|
||||
|
||||
INSN(fcvt_w_s, 0b1010011, 0b00000, 0b1100000);
|
||||
INSN(fcvt_l_s, 0b1010011, 0b00010, 0b1100000);
|
||||
INSN(fcvt_wu_s, 0b1010011, 0b00001, 0b1100000);
|
||||
INSN(fcvt_lu_s, 0b1010011, 0b00011, 0b1100000);
|
||||
INSN(fcvt_w_d, 0b1010011, 0b00000, 0b1100001);
|
||||
INSN(fcvt_wu_d, 0b1010011, 0b00001, 0b1100001);
|
||||
INSN(fcvt_l_d, 0b1010011, 0b00010, 0b1100001);
|
||||
INSN(fcvt_lu_d, 0b1010011, 0b00011, 0b1100001);
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Move Instruction
|
||||
#define INSN(NAME, op, funct3, funct5, funct7) \
|
||||
void NAME(FloatRegister Rd, Register Rs1) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, funct3); \
|
||||
patch((address)&insn, 20, funct5); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(Register Rd, FloatRegister Rs1, uint8_t Rs2, RoundingMode rm) {
|
||||
guarantee(is_uimm5(Rs2), "Rs2 is out of validity");
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, rm);
|
||||
}
|
||||
|
||||
INSN(fmv_h_x, 0b1010011, 0b000, 0b00000, 0b1111010);
|
||||
INSN(fmv_w_x, 0b1010011, 0b000, 0b00000, 0b1111000);
|
||||
INSN(fmv_d_x, 0b1010011, 0b000, 0b00000, 0b1111001);
|
||||
|
||||
#undef INSN
|
||||
|
||||
enum fclass_mask {
|
||||
minf = 1 << 0, // negative infinite
|
||||
mnorm = 1 << 1, // negative normal number
|
||||
msubnorm = 1 << 2, // negative subnormal number
|
||||
mzero = 1 << 3, // negative zero
|
||||
pzero = 1 << 4, // positive zero
|
||||
psubnorm = 1 << 5, // positive subnormal number
|
||||
pnorm = 1 << 6, // positive normal number
|
||||
pinf = 1 << 7, // positive infinite
|
||||
snan = 1 << 8, // signaling NaN
|
||||
qnan = 1 << 9, // quiet NaN
|
||||
zero = mzero | pzero,
|
||||
subnorm = msubnorm | psubnorm,
|
||||
norm = mnorm | pnorm,
|
||||
inf = minf | pinf,
|
||||
nan = snan | qnan,
|
||||
finite = zero | subnorm | norm,
|
||||
};
|
||||
|
||||
// Float and Double Conversion/Classify Instruction
|
||||
#define INSN(NAME, op, funct3, funct5, funct7) \
|
||||
void NAME(Register Rd, FloatRegister Rs1) { \
|
||||
unsigned insn = 0; \
|
||||
patch((address)&insn, 6, 0, op); \
|
||||
patch((address)&insn, 14, 12, funct3); \
|
||||
patch((address)&insn, 20, funct5); \
|
||||
patch((address)&insn, 31, 25, funct7); \
|
||||
patch_reg((address)&insn, 7, Rd); \
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn); \
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(Register Rd, FloatRegister Rs1, uint8_t Rs2, uint8_t rm) {
|
||||
guarantee(is_uimm5(Rs2), "Rs2 is out of validity");
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm);
|
||||
}
|
||||
|
||||
INSN(fclass_h, 0b1010011, 0b001, 0b00000, 0b1110010);
|
||||
INSN(fclass_s, 0b1010011, 0b001, 0b00000, 0b1110000);
|
||||
INSN(fclass_d, 0b1010011, 0b001, 0b00000, 0b1110001);
|
||||
INSN(fmv_x_h, 0b1010011, 0b000, 0b00000, 0b1110010);
|
||||
INSN(fmv_x_w, 0b1010011, 0b000, 0b00000, 0b1110000);
|
||||
INSN(fmv_x_d, 0b1010011, 0b000, 0b00000, 0b1110001);
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(FloatRegister Rd, Register Rs1, uint8_t Rs2, RoundingMode rm) {
|
||||
guarantee(is_uimm5(Rs2), "Rs2 is out of validity");
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, rm);
|
||||
}
|
||||
|
||||
#undef INSN
|
||||
template <FmtPrecision Fmt, uint8_t funct5>
|
||||
void fp_base(FloatRegister Rd, Register Rs1, uint8_t Rs2, int8_t rm) {
|
||||
guarantee(is_uimm5(Rs2), "Rs2 is out of validity");
|
||||
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
enum FClassBits {
|
||||
minf = 1 << 0, // negative infinite
|
||||
mnorm = 1 << 1, // negative normal number
|
||||
msubnorm = 1 << 2, // negative subnormal number
|
||||
mzero = 1 << 3, // negative zero
|
||||
pzero = 1 << 4, // positive zero
|
||||
psubnorm = 1 << 5, // positive subnormal number
|
||||
pnorm = 1 << 6, // positive normal number
|
||||
pinf = 1 << 7, // positive infinite
|
||||
snan = 1 << 8, // signaling NaN
|
||||
qnan = 1 << 9, // quiet NaN
|
||||
zero = mzero | pzero,
|
||||
subnorm = msubnorm | psubnorm,
|
||||
norm = mnorm | pnorm,
|
||||
inf = minf | pinf,
|
||||
nan = snan | qnan,
|
||||
finite = zero | subnorm | norm,
|
||||
};
|
||||
|
||||
void fsqrt_s(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b01011>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fsqrt_d(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b01011>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fcvt_s_d(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b01000>(Rd, Rs1, 0b00001, rm);
|
||||
}
|
||||
|
||||
void fcvt_d_s(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b01000>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fsgnj_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b00100>(Rd, Rs1, Rs2, 0b000);
|
||||
}
|
||||
|
||||
void fsgnjn_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b00100>(Rd, Rs1, Rs2, 0b001);
|
||||
}
|
||||
|
||||
void fsgnjx_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b00100>(Rd, Rs1, Rs2, 0b010);
|
||||
}
|
||||
|
||||
void fmin_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b00101>(Rd, Rs1, Rs2, 0b000);
|
||||
}
|
||||
|
||||
void fmax_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b00101>(Rd, Rs1, Rs2, 0b001);
|
||||
}
|
||||
|
||||
void fsgnj_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b00100>(Rd, Rs1, Rs2, 0b000);
|
||||
}
|
||||
|
||||
void fsgnjn_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b00100>(Rd, Rs1, Rs2, 0b001);
|
||||
}
|
||||
|
||||
void fsgnjx_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b00100>(Rd, Rs1, Rs2, 0b010);
|
||||
}
|
||||
|
||||
void fmin_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b00101>(Rd, Rs1, Rs2, 0b000);
|
||||
}
|
||||
|
||||
void fmax_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b00101>(Rd, Rs1, Rs2, 0b001);
|
||||
}
|
||||
|
||||
void feq_s(Register Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b10100>(Rd, Rs1, Rs2, 0b010);
|
||||
}
|
||||
|
||||
void flt_s(Register Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b10100>(Rd, Rs1, Rs2, 0b001);
|
||||
}
|
||||
|
||||
void fle_s(Register Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<S_32_sp, 0b10100>(Rd, Rs1, Rs2, 0b000);
|
||||
}
|
||||
|
||||
void feq_d(Register Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b10100>(Rd, Rs1, Rs2, 0b010);
|
||||
}
|
||||
|
||||
void fle_d(Register Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b10100>(Rd, Rs1, Rs2, 0b000);
|
||||
}
|
||||
|
||||
void flt_d(Register Rd, FloatRegister Rs1, FloatRegister Rs2) {
|
||||
fp_base<D_64_dp, 0b10100>(Rd, Rs1, Rs2, 0b001);
|
||||
}
|
||||
|
||||
void fadd_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b00000>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fsub_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b00001>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fmul_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b00010>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fdiv_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b00011>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fadd_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b00000>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fsub_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b00001>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fmul_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b00010>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fdiv_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b00011>(Rd, Rs1, Rs2, rm);
|
||||
}
|
||||
|
||||
void fcvt_s_w(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b11010>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fcvt_s_wu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b11010>(Rd, Rs1, 0b00001, rm);
|
||||
}
|
||||
|
||||
void fcvt_s_l(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b11010>(Rd, Rs1, 0b00010, rm);
|
||||
}
|
||||
|
||||
void fcvt_s_lu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<S_32_sp, 0b11010>(Rd, Rs1, 0b00011, rm);
|
||||
}
|
||||
|
||||
void fcvt_d_w(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b11010>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fcvt_d_wu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b11010>(Rd, Rs1, 0b00001, rm);
|
||||
}
|
||||
|
||||
void fcvt_d_l(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b11010>(Rd, Rs1, 0b00010, rm);
|
||||
}
|
||||
|
||||
void fcvt_d_lu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) {
|
||||
fp_base<D_64_dp, 0b11010>(Rd, Rs1, 0b00011, rm);
|
||||
}
|
||||
|
||||
void fcvt_w_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<S_32_sp, 0b11000>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fcvt_l_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<S_32_sp, 0b11000>(Rd, Rs1, 0b00010, rm);
|
||||
}
|
||||
|
||||
void fcvt_wu_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<S_32_sp, 0b11000>(Rd, Rs1, 0b00001, rm);
|
||||
}
|
||||
|
||||
void fcvt_lu_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<S_32_sp, 0b11000>(Rd, Rs1, 0b00011, rm);
|
||||
}
|
||||
|
||||
void fcvt_w_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<D_64_dp, 0b11000>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fcvt_wu_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<D_64_dp, 0b11000>(Rd, Rs1, 0b00001, rm);
|
||||
}
|
||||
|
||||
void fcvt_l_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<D_64_dp, 0b11000>(Rd, Rs1, 0b00010, rm);
|
||||
}
|
||||
|
||||
void fcvt_lu_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) {
|
||||
fp_base<D_64_dp, 0b11000>(Rd, Rs1, 0b00011, rm);
|
||||
}
|
||||
|
||||
void fmv_w_x(FloatRegister Rd, Register Rs1) {
|
||||
fp_base<S_32_sp, 0b11110>(Rd, Rs1, 0b00000, 0b000);
|
||||
}
|
||||
|
||||
void fmv_d_x(FloatRegister Rd, Register Rs1) {
|
||||
fp_base<D_64_dp, 0b11110>(Rd, Rs1, 0b00000, 0b000);
|
||||
}
|
||||
|
||||
void fclass_s(Register Rd, FloatRegister Rs1) {
|
||||
fp_base<S_32_sp, 0b11100>(Rd, Rs1, 0b00000, 0b001);
|
||||
}
|
||||
|
||||
void fclass_d(Register Rd, FloatRegister Rs1) {
|
||||
fp_base<D_64_dp, 0b11100>(Rd, Rs1, 0b00000, 0b001);
|
||||
}
|
||||
|
||||
void fmv_x_w(Register Rd, FloatRegister Rs1) {
|
||||
fp_base<S_32_sp, 0b11100>(Rd, Rs1, 0b00000, 0b000);
|
||||
}
|
||||
|
||||
void fmv_x_d(Register Rd, FloatRegister Rs1) {
|
||||
fp_base<D_64_dp, 0b11100>(Rd, Rs1, 0b00000, 0b000);
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr unsigned int OP_LOAD_FP = 0b0000111;
|
||||
|
||||
template <int8_t FpWidth>
|
||||
void fp_load(FloatRegister Rd, Register Rs, const int32_t offset) {
|
||||
guarantee(is_uimm3(FpWidth), "Rounding mode is out of validity");
|
||||
guarantee(is_simm12(offset), "offset is invalid.");
|
||||
unsigned insn = 0;
|
||||
uint32_t val = offset & 0xfff;
|
||||
patch((address)&insn, 6, 0, OP_LOAD_FP);
|
||||
patch_reg((address)&insn, 7, Rd);
|
||||
patch((address)&insn, 14, 12, FpWidth);
|
||||
patch_reg((address)&insn, 15, Rs);
|
||||
patch((address)&insn, 31, 20, val);
|
||||
emit(insn);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void flw(FloatRegister Rd, Register Rs, const int32_t offset) { fp_load<0b010>(Rd, Rs, offset); }
|
||||
void _fld(FloatRegister Rd, Register Rs, const int32_t offset) { fp_load<0b011>(Rd, Rs, offset); }
|
||||
|
||||
private:
|
||||
template <FmtPrecision Fmt, uint8_t OpVal>
|
||||
void fp_fm(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm) {
|
||||
assert_cond(Fmt != Q_128_qp);
|
||||
guarantee(is_uimm3(rm), "Rounding mode is out of validity");
|
||||
guarantee(is_uimm2(Fmt), "FMT is out of validity");
|
||||
unsigned insn = 0;
|
||||
patch((address)&insn, 6, 0, OpVal);
|
||||
patch_reg((address)&insn, 7, Rd);
|
||||
patch((address)&insn, 14, 12, rm);
|
||||
patch_reg((address)&insn, 15, Rs1);
|
||||
patch_reg((address)&insn, 20, Rs2);
|
||||
patch((address)&insn, 26, 25, Fmt);
|
||||
patch_reg((address)&insn, 27, Rs3);
|
||||
emit(insn);
|
||||
}
|
||||
|
||||
public:
|
||||
void fmadd_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<S_32_sp, 0b1000011>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fmsub_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<S_32_sp, 0b1000111>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fnmsub_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<S_32_sp, 0b1001011>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fnmadd_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<S_32_sp, 0b1001111>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fmadd_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<D_64_dp, 0b1000011>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fmsub_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<D_64_dp, 0b1000111>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fnmsub_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<D_64_dp, 0b1001011>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
void fnmadd_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) {
|
||||
fp_fm<D_64_dp, 0b1001111>(Rd, Rs1, Rs2, Rs3, rm);
|
||||
}
|
||||
|
||||
// -------------- ZFH Instruction Definitions --------------
|
||||
// Zfh Standard Extensions for Half-Precision Floating-Point
|
||||
void fclass_h(Register Rd, FloatRegister Rs1) {
|
||||
assert_cond(UseZfh);
|
||||
fp_base<H_16_hp, 0b11100>(Rd, Rs1, 0b00000, 0b001);
|
||||
}
|
||||
|
||||
// Zfh and Zfhmin Half-Precision Floating-Point
|
||||
void fcvt_s_h(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) {
|
||||
assert_cond(UseZfh || UseZfhmin);
|
||||
fp_base<S_32_sp, 0b01000>(Rd, Rs1, 0b00010, rm);
|
||||
}
|
||||
|
||||
void fcvt_h_s(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) {
|
||||
assert_cond(UseZfh || UseZfhmin);
|
||||
fp_base<H_16_hp, 0b01000>(Rd, Rs1, 0b00000, rm);
|
||||
}
|
||||
|
||||
void fmv_h_x(FloatRegister Rd, Register Rs1) {
|
||||
assert_cond(UseZfh || UseZfhmin);
|
||||
fp_base<H_16_hp, 0b11110>(Rd, Rs1, 0b00000, 0b000);
|
||||
}
|
||||
|
||||
void fmv_x_h(Register Rd, FloatRegister Rs1) {
|
||||
assert_cond(UseZfh || UseZfhmin);
|
||||
fp_base<H_16_hp, 0b11100>(Rd, Rs1, 0b00000, 0b000);
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// RISC-V Vector Extension
|
||||
@ -3402,6 +3563,7 @@ public:
|
||||
static bool is_simm18(int64_t x);
|
||||
static bool is_simm21(int64_t x);
|
||||
|
||||
static bool is_uimm2(uint64_t x);
|
||||
static bool is_uimm3(uint64_t x);
|
||||
static bool is_uimm5(uint64_t x);
|
||||
static bool is_uimm6(uint64_t x);
|
||||
|
||||
@ -38,6 +38,7 @@ inline bool Assembler::is_simm13(int64_t x) { return is_simm(x, 13); }
|
||||
inline bool Assembler::is_simm18(int64_t x) { return is_simm(x, 18); }
|
||||
inline bool Assembler::is_simm21(int64_t x) { return is_simm(x, 21); }
|
||||
|
||||
inline bool Assembler::is_uimm2(uint64_t x) { return is_uimm(x, 2); }
|
||||
inline bool Assembler::is_uimm3(uint64_t x) { return is_uimm(x, 3); }
|
||||
inline bool Assembler::is_uimm5(uint64_t x) { return is_uimm(x, 5); }
|
||||
inline bool Assembler::is_uimm6(uint64_t x) { return is_uimm(x, 6); }
|
||||
|
||||
@ -2058,7 +2058,7 @@ void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRe
|
||||
is_double ? fclass_d(t1, src2)
|
||||
: fclass_s(t1, src2);
|
||||
orr(t0, t0, t1);
|
||||
andi(t0, t0, fclass_mask::nan); // if src1 or src2 is quiet or signaling NaN then return NaN
|
||||
andi(t0, t0, FClassBits::nan); // if src1 or src2 is quiet or signaling NaN then return NaN
|
||||
beqz(t0, Compare);
|
||||
is_double ? fadd_d(dst, src1, src2)
|
||||
: fadd_s(dst, src1, src2);
|
||||
@ -2152,7 +2152,7 @@ void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister one, bool is_
|
||||
: fclass_s(t0, dst);
|
||||
|
||||
// check if input is -0, +0, signaling NaN or quiet NaN
|
||||
andi(t0, t0, fclass_mask::zero | fclass_mask::nan);
|
||||
andi(t0, t0, FClassBits::zero | FClassBits::nan);
|
||||
|
||||
bnez(t0, done);
|
||||
|
||||
@ -2368,7 +2368,7 @@ void C2_MacroAssembler::signum_fp_v(VectorRegister dst, VectorRegister one, Basi
|
||||
|
||||
// check if input is -0, +0, signaling NaN or quiet NaN
|
||||
vfclass_v(v0, dst);
|
||||
mv(t0, fclass_mask::zero | fclass_mask::nan);
|
||||
mv(t0, FClassBits::zero | FClassBits::nan);
|
||||
vand_vx(v0, v0, t0);
|
||||
vmseq_vi(v0, v0, 0);
|
||||
|
||||
|
||||
@ -104,6 +104,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
product(bool, UseZbb, false, DIAGNOSTIC, "Use Zbb instructions") \
|
||||
product(bool, UseZbs, false, DIAGNOSTIC, "Use Zbs instructions") \
|
||||
product(bool, UseZfh, false, DIAGNOSTIC, "Use Zfh instructions") \
|
||||
product(bool, UseZfhmin, false, DIAGNOSTIC, "Use Zfhmin instructions") \
|
||||
product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \
|
||||
product(bool, UseZcb, false, EXPERIMENTAL, "Use Zcb instructions") \
|
||||
product(bool, UseZic64b, false, EXPERIMENTAL, "Use Zic64b instructions") \
|
||||
|
||||
@ -5886,7 +5886,7 @@ void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register t
|
||||
fclass_##FLOATSIG(tmp, src); \
|
||||
mv(dst, zr); \
|
||||
/* check if src is NaN */ \
|
||||
andi(tmp, tmp, fclass_mask::nan); \
|
||||
andi(tmp, tmp, FClassBits::nan); \
|
||||
bnez(tmp, done); \
|
||||
FLOATCVT(dst, src); \
|
||||
bind(done); \
|
||||
|
||||
@ -1918,7 +1918,7 @@ bool Matcher::match_rule_supported(int opcode) {
|
||||
|
||||
case Op_ConvHF2F:
|
||||
case Op_ConvF2HF:
|
||||
return UseZfh;
|
||||
return UseZfh || UseZfhmin;
|
||||
}
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
@ -7348,7 +7348,7 @@ instruct isInfiniteF_reg_reg(iRegINoSp dst, fRegF src)
|
||||
format %{ "isInfinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::inf);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@ -7363,7 +7363,7 @@ instruct isInfiniteD_reg_reg(iRegINoSp dst, fRegD src)
|
||||
format %{ "isInfinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::inf);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@ -7378,7 +7378,7 @@ instruct isFiniteF_reg_reg(iRegINoSp dst, fRegF src)
|
||||
format %{ "isFinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::finite);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@ -7393,7 +7393,7 @@ instruct isFiniteD_reg_reg(iRegINoSp dst, fRegD src)
|
||||
format %{ "isFinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::finite);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
|
||||
@ -115,6 +115,7 @@ class VM_Version : public Abstract_VM_Version {
|
||||
// Zbs Single-bit instructions
|
||||
//
|
||||
// Zfh Half-Precision Floating-Point instructions
|
||||
// Zfhmin Minimal Half-Precision Floating-Point instructions
|
||||
//
|
||||
// Zicond Conditional operations
|
||||
//
|
||||
@ -157,6 +158,7 @@ class VM_Version : public Abstract_VM_Version {
|
||||
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
|
||||
decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
|
||||
decl(ext_Zfh , "Zfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
|
||||
decl(ext_Zfhmin , "Zfhmin" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \
|
||||
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zicntr , "Zicntr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
@ -224,6 +226,7 @@ class VM_Version : public Abstract_VM_Version {
|
||||
RV_ENABLE_EXTENSION(UseZbb) \
|
||||
RV_ENABLE_EXTENSION(UseZbs) \
|
||||
RV_ENABLE_EXTENSION(UseZcb) \
|
||||
RV_ENABLE_EXTENSION(UseZfhmin) \
|
||||
RV_ENABLE_EXTENSION(UseZic64b) \
|
||||
RV_ENABLE_EXTENSION(UseZicbom) \
|
||||
RV_ENABLE_EXTENSION(UseZicbop) \
|
||||
|
||||
@ -177,6 +177,9 @@ void RiscvHwprobe::add_features_from_query_result() {
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZFH)) {
|
||||
VM_Version::ext_Zfh.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZFHMIN)) {
|
||||
VM_Version::ext_Zfhmin.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVBC)) {
|
||||
VM_Version::ext_Zvbc.enable_feature();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user