let ParserMatchClass = GPRPF64AsFPR;
}
-def DExt : ExtInfo<0, [HasStdExtD]>;
-def ZdinxExt : ExtInfo<1, [HasStdExtZdinx, IsRV64]>;
-def Zdinx32Ext : ExtInfo<2, [HasStdExtZdinx, IsRV32]>;
-
-def D : ExtInfo_r<DExt, FPR64>;
-def D_INX : ExtInfo_r<ZdinxExt, FPR64INX>;
-def D_IN32X : ExtInfo_r<Zdinx32Ext, FPR64IN32X>;
-
-def DD : ExtInfo_rr<DExt, FPR64, FPR64>;
-def DD_INX : ExtInfo_rr<ZdinxExt, FPR64INX, FPR64INX>;
-def DD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR64IN32X>;
-def DF : ExtInfo_rr<DExt, FPR64, FPR32>;
-def DF_INX : ExtInfo_rr<ZdinxExt, FPR64INX, FPR32INX>;
-def DF_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR32INX>;
-def DX : ExtInfo_rr<DExt, FPR64, GPR>;
-def DX_INX : ExtInfo_rr<ZdinxExt, FPR64INX, GPR>;
-def DX_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, GPR>;
-def FD : ExtInfo_rr<DExt, FPR32, FPR64>;
-def FD_INX : ExtInfo_rr<ZdinxExt, FPR32INX, FPR64INX>;
-def FD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR32INX, FPR64IN32X>;
-def XD : ExtInfo_rr<DExt, GPR, FPR64>;
-def XD_INX : ExtInfo_rr<ZdinxExt, GPR, FPR64INX>;
-def XD_IN32X : ExtInfo_rr<Zdinx32Ext, GPR, FPR64IN32X>;
-
-defvar DINX = [D, D_INX, D_IN32X];
-defvar DDINX = [DD, DD_INX, DD_IN32X];
-defvar DXINX = [DX, DX_INX, DX_IN32X];
-defvar DFINX = [DF, DF_INX, DF_IN32X];
-defvar FDINX = [FD, FD_INX, FD_IN32X];
-defvar XDINX = [XD, XD_INX, XD_IN32X];
-
-// Lists without the IN32X classes that aren't needed for some RV64-only
-// instructions.
-defvar DXINXRV64 = [DX, DX_INX];
-defvar XDINXRV64 = [XD, XD_INX];
+def DExt : ExtInfo<"", "", [HasStdExtD], FPR64, FPR32, FPR64, ?>;
+
+def ZdinxExt : ExtInfo<"_INX", "RVZfinx", [HasStdExtZdinx, IsRV64],
+ FPR64INX, FPR32INX, FPR64INX, ?>;
+def Zdinx32Ext : ExtInfo<"_IN32X", "RV32Zdinx", [HasStdExtZdinx, IsRV32],
+ FPR64IN32X, FPR32INX, FPR64IN32X, ?>;
+
+defvar DExts = [DExt, ZdinxExt, Zdinx32Ext];
+defvar DExtsRV64 = [DExt, ZdinxExt];
//===----------------------------------------------------------------------===//
// Instructions
def FSD : FPStore_r<0b011, "fsd", FPR64, WriteFST64>;
} // Predicates = [HasStdExtD]
-let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in {
-defm FMADD_D : FPFMA_rrr_frm_m<OPC_MADD, 0b01, "fmadd.d", DINX>;
-defm FMSUB_D : FPFMA_rrr_frm_m<OPC_MSUB, 0b01, "fmsub.d", DINX>;
-defm FNMSUB_D : FPFMA_rrr_frm_m<OPC_NMSUB, 0b01, "fnmsub.d", DINX>;
-defm FNMADD_D : FPFMA_rrr_frm_m<OPC_NMADD, 0b01, "fnmadd.d", DINX>;
-}
-
-let SchedRW = [WriteFAdd64, ReadFAdd64, ReadFAdd64] in {
-defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX, /*Commutable*/1>;
-defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", DINX>;
-}
-let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
-defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX, /*Commutable*/1>;
-
-let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
-defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>;
-
-defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, DDINX, "fsqrt.d">,
- Sched<[WriteFSqrt64, ReadFSqrt64]>;
-
-let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64],
- mayRaiseFPException = 0 in {
-defm FSGNJ_D : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d", DINX>;
-defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", DINX>;
-defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", DINX>;
-}
-
-let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
-defm FMIN_D : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX, /*Commutable*/1>;
-defm FMAX_D : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX, /*Commutable*/1>;
-}
-
-defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, FDINX, "fcvt.s.d">,
- Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
-
-defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, DFINX, "fcvt.d.s">,
- Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
-
-let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
-defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX, /*Commutable*/1>;
-defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", DINX>;
-defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", DINX>;
-}
+foreach Ext = DExts in {
+ let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in {
+ defm FMADD_D : FPFMA_rrr_frm_m<OPC_MADD, 0b01, "fmadd.d", Ext>;
+ defm FMSUB_D : FPFMA_rrr_frm_m<OPC_MSUB, 0b01, "fmsub.d", Ext>;
+ defm FNMSUB_D : FPFMA_rrr_frm_m<OPC_NMSUB, 0b01, "fnmsub.d", Ext>;
+ defm FNMADD_D : FPFMA_rrr_frm_m<OPC_NMADD, 0b01, "fnmadd.d", Ext>;
+ }
+
+ let SchedRW = [WriteFAdd64, ReadFAdd64, ReadFAdd64] in {
+ defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", Ext, /*Commutable*/1>;
+ defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", Ext>;
+ }
+ let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
+ defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", Ext, /*Commutable*/1>;
+
+ let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
+ defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", Ext>;
+
+ defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, Ext, Ext.PrimaryTy,
+ Ext.PrimaryTy, "fsqrt.d">,
+ Sched<[WriteFSqrt64, ReadFSqrt64]>;
+
+ let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64],
+ mayRaiseFPException = 0 in {
+ defm FSGNJ_D : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d", Ext>;
+ defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", Ext>;
+ defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", Ext>;
+ }
+
+ let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
+ defm FMIN_D : FPALU_rr_m<0b0010101, 0b000, "fmin.d", Ext, /*Commutable*/1>;
+ defm FMAX_D : FPALU_rr_m<0b0010101, 0b001, "fmax.d", Ext, /*Commutable*/1>;
+ }
+
+ defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, Ext, Ext.F32Ty,
+ Ext.PrimaryTy, "fcvt.s.d">,
+ Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
+
+ defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, Ext, Ext.PrimaryTy,
+ Ext.F32Ty, "fcvt.d.s">,
+ Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
+
+ let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
+ defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", Ext, /*Commutable*/1>;
+ defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", Ext>;
+ defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", Ext>;
+ }
+
+ let mayRaiseFPException = 0 in
+ defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, Ext, GPR, Ext.PrimaryTy,
+ "fclass.d">,
+ Sched<[WriteFClass64, ReadFClass64]>;
+
+ let IsSignExtendingOpW = 1 in
+ defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.w.d">,
+ Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
-let mayRaiseFPException = 0 in
-defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, XDINX, "fclass.d">,
- Sched<[WriteFClass64, ReadFClass64]>;
+ let IsSignExtendingOpW = 1 in
+ defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.wu.d">,
+ Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
-let IsSignExtendingOpW = 1 in
-defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, XDINX, "fcvt.w.d">,
- Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
+ defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.d.w">,
+ Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
-let IsSignExtendingOpW = 1 in
-defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, XDINX, "fcvt.wu.d">,
- Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
+ defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.d.wu">,
+ Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
+} // foreach Ext = DExts
-defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, DXINX, "fcvt.d.w">,
- Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
+foreach Ext = DExtsRV64 in {
+ defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.l.d", [IsRV64]>,
+ Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
-defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, DXINX, "fcvt.d.wu">,
- Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
+ defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.lu.d", [IsRV64]>,
+ Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
-defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, XDINXRV64, "fcvt.l.d", [IsRV64]>,
- Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
+ defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.d.l", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
-defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, XDINXRV64, "fcvt.lu.d", [IsRV64]>,
- Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
+ defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.d.lu", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
+} // foreach Ext = DExts64
let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
def FMV_X_D : FPUnaryOp_r<0b1110001, 0b00000, 0b000, GPR, FPR64, "fmv.x.d">,
Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>;
-defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, DXINXRV64, "fcvt.d.l", [IsRV64]>,
- Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
-
-defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, DXINXRV64, "fcvt.d.lu", [IsRV64]>,
- Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
-
let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
def FMV_D_X : FPUnaryOp_r<0b1111001, 0b00000, 0b000, FPR64, GPR, "fmv.d.x">,
Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>;
/// Float arithmetic operations
-defm : PatFprFprDynFrm_m<any_fadd, FADD_D, DINX>;
-defm : PatFprFprDynFrm_m<any_fsub, FSUB_D, DINX>;
-defm : PatFprFprDynFrm_m<any_fmul, FMUL_D, DINX>;
-defm : PatFprFprDynFrm_m<any_fdiv, FDIV_D, DINX>;
+foreach Ext = DExts in {
+ defm : PatFprFprDynFrm_m<any_fadd, FADD_D, Ext>;
+ defm : PatFprFprDynFrm_m<any_fsub, FSUB_D, Ext>;
+ defm : PatFprFprDynFrm_m<any_fmul, FMUL_D, Ext>;
+ defm : PatFprFprDynFrm_m<any_fdiv, FDIV_D, Ext>;
+}
let Predicates = [HasStdExtD] in {
def : Pat<(any_fsqrt FPR64:$rs1), (FSQRT_D FPR64:$rs1, FRM_DYN)>;
// The ratified 20191213 ISA spec defines fmin and fmax in a way that matches
// LLVM's fminnum and fmaxnum.
// <https://github.com/riscv/riscv-isa-manual/commit/cd20cee7efd9bac7c5aa127ec3b451749d2b3cce>.
-defm : PatFprFpr_m<fminnum, FMIN_D, DINX>;
-defm : PatFprFpr_m<fmaxnum, FMAX_D, DINX>;
+foreach Ext = DExts in {
+ defm : PatFprFpr_m<fminnum, FMIN_D, Ext>;
+ defm : PatFprFpr_m<fmaxnum, FMAX_D, Ext>;
+}
/// Setcc
// FIXME: SETEQ/SETLT/SETLE imply nonans, can we pick better instructions for
// strict versions of those.
// Match non-signaling FEQ_D
-defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_D, DINX>;
-defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_D, DINX>;
-defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_D, DINX>;
-defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_D, DINX>;
-defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_D, DINX>;
-defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_D, DINX>;
+foreach Ext = DExts in {
+ defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_D, Ext>;
+ defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_D, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_D, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_D, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_D, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_D, Ext>;
+}
let Predicates = [HasStdExtD] in {
// Match signaling FEQ_D
let DecoderMethod = "DecodeGPRRegisterClass";
}
-// inx = 0 : f, d, zfh, zfhmin
-// = 1 : zfinx, zdinx, zhinx, zhinxmin
-// = 2 : zdinx_rv32
-class ExtInfo<bits<2> inx, list<Predicate> pres> {
- string Suffix = !cond(!eq(inx, 0): "",
- !eq(inx, 1): "_INX",
- !eq(inx, 2): "_IN32X");
- list<Predicate> Predicates = pres;
- string Space = !cond(!eq(inx, 0): "",
- !eq(inx, 1): "RVZfinx",
- !eq(inx, 2): "RV32Zdinx");
-}
-
-class ExtInfo_r<ExtInfo ext, DAGOperand reg> {
- string Suffix = ext.Suffix;
- list<Predicate> Predicates = ext.Predicates;
- string Space = ext.Space;
- DAGOperand Reg = reg;
-}
-
-class ExtInfo_rr<ExtInfo ext, DAGOperand rdty, DAGOperand rs1ty> {
- string Suffix = ext.Suffix;
- list<Predicate> Predicates = ext.Predicates;
- string Space = ext.Space;
- DAGOperand RdTy = rdty;
- DAGOperand Rs1Ty = rs1ty;
+// Describes a combination of predicates from F/D/Zfh/Zfhmin or
+// Zfinx/Zdinx/Zhinx/Zhinxmin that are applied to scalar FP instruction.
+// Contains the DAGOperand for the primary type for the predicates. The primary
+// type may be unset for combinations of predicates like Zfh+D.
+// Also contains the DAGOperand for f16/f32/f64, instruction suffix, and
+// decoder namespace that go with an instruction given those predicates.
+//
+// The DAGOperand can be unset if the predicates are not enough to define it.
+class ExtInfo<string suffix, string space, list<Predicate> predicates,
+ DAGOperand primaryty, DAGOperand f32ty, DAGOperand f64ty,
+ DAGOperand f16ty> {
+ list<Predicate> Predicates = predicates;
+ string Suffix = suffix;
+ string Space = space;
+ DAGOperand PrimaryTy = primaryty;
+ DAGOperand F16Ty = f16ty;
+ DAGOperand F32Ty = f32ty;
+ DAGOperand F64Ty = f64ty;
}
-def FExt : ExtInfo<0, [HasStdExtF]>;
-def ZfinxExt : ExtInfo<1, [HasStdExtZfinx]>;
-
-def F : ExtInfo_r<FExt, FPR32>;
-def F_INX : ExtInfo_r<ZfinxExt, FPR32INX>;
+def FExt : ExtInfo<"", "", [HasStdExtF], FPR32, FPR32, ?, ?>;
-def FF : ExtInfo_rr<FExt, FPR32, FPR32>;
-def FF_INX : ExtInfo_rr<ZfinxExt, FPR32INX, FPR32INX>;
-def FX : ExtInfo_rr<FExt, FPR32, GPR>;
-def FX_INX : ExtInfo_rr<ZfinxExt, FPR32INX, GPR>;
-def XF : ExtInfo_rr<FExt, GPR, FPR32>;
-def XF_INX : ExtInfo_rr<ZfinxExt, GPR, FPR32INX>;
+def ZfinxExt : ExtInfo<"_INX", "RVZfinx", [HasStdExtZfinx], FPR32INX, FPR32INX, ?, ?>;
-defvar FINX = [F, F_INX];
-defvar FFINX = [FF, FF_INX];
-defvar FXINX = [FX, FX_INX];
-defvar XFINX = [XF, XF_INX];
+defvar FExts = [FExt, ZfinxExt];
// Floating-point rounding mode
opcodestr, "$rd, $rs1, $rs2, $rs3$frm">;
multiclass FPFMA_rrr_frm_m<RISCVOpcode opcode, bits<2> funct2,
- string opcodestr, list<ExtInfo_r> Exts> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
- def Ext.Suffix : FPFMA_rrr_frm<opcode, funct2, opcodestr, Ext.Reg>;
+ string opcodestr, ExtInfo Ext> {
+ let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+ def Ext.Suffix : FPFMA_rrr_frm<opcode, funct2, opcodestr, Ext.PrimaryTy>;
}
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
let isCommutable = Commutable;
}
multiclass FPALU_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr,
- list<ExtInfo_r> Exts, bit Commutable = 0> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
- def Ext.Suffix : FPALU_rr<funct7, funct3, opcodestr, Ext.Reg, Commutable>;
+ ExtInfo Ext, bit Commutable = 0> {
+ let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+ def Ext.Suffix : FPALU_rr<funct7, funct3, opcodestr, Ext.PrimaryTy, Commutable>;
}
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
let isCommutable = Commutable;
}
multiclass FPALU_rr_frm_m<bits<7> funct7, string opcodestr,
- list<ExtInfo_r> Exts, bit Commutable = 0> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
- def Ext.Suffix : FPALU_rr_frm<funct7, opcodestr, Ext.Reg, Commutable>;
+ ExtInfo Ext, bit Commutable = 0> {
+ let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+ def Ext.Suffix : FPALU_rr_frm<funct7, opcodestr, Ext.PrimaryTy, Commutable>;
}
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
let rs2 = rs2val;
}
multiclass FPUnaryOp_r_m<bits<7> funct7, bits<5> rs2val, bits<3> funct3,
- list<ExtInfo_rr> Exts, string opcodestr> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
- def Ext.Suffix : FPUnaryOp_r<funct7, rs2val, funct3, Ext.RdTy, Ext.Rs1Ty,
- opcodestr>;
+ ExtInfo Ext, DAGOperand rdty, DAGOperand rs1ty,
+ string opcodestr> {
+ let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+ def Ext.Suffix : FPUnaryOp_r<funct7, rs2val, funct3, rdty, rs1ty, opcodestr>;
}
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
let rs2 = rs2val;
}
multiclass FPUnaryOp_r_frm_m<bits<7> funct7, bits<5> rs2val,
- list<ExtInfo_rr> Exts, string opcodestr,
- list<Predicate> ExtraPreds = []> {
- foreach Ext = Exts in
- let Predicates = !listconcat(Ext.Predicates, ExtraPreds),
- DecoderNamespace = Ext.Space in
- def Ext.Suffix : FPUnaryOp_r_frm<funct7, rs2val, Ext.RdTy, Ext.Rs1Ty,
- opcodestr>;
+ ExtInfo Ext, DAGOperand rdty, DAGOperand rs1ty,
+ string opcodestr, list<Predicate> ExtraPreds = []> {
+ let Predicates = !listconcat(Ext.Predicates, ExtraPreds),
+ DecoderNamespace = Ext.Space in
+ def Ext.Suffix : FPUnaryOp_r_frm<funct7, rs2val, rdty, rs1ty,
+ opcodestr>;
}
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
let isCommutable = Commutable;
}
multiclass FPCmp_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr,
- list<ExtInfo_r> Exts, bit Commutable = 0> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
- def Ext.Suffix : FPCmp_rr<funct7, funct3, opcodestr, Ext.Reg, Commutable>;
+ ExtInfo Ext, bit Commutable = 0> {
+ let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
+ def Ext.Suffix : FPCmp_rr<funct7, funct3, opcodestr, Ext.PrimaryTy, Commutable>;
}
class PseudoFROUND<DAGOperand Ty>
def FSW : FPStore_r<0b010, "fsw", FPR32, WriteFST32>;
} // Predicates = [HasStdExtF]
-let SchedRW = [WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32] in {
-defm FMADD_S : FPFMA_rrr_frm_m<OPC_MADD, 0b00, "fmadd.s", FINX>;
-defm FMSUB_S : FPFMA_rrr_frm_m<OPC_MSUB, 0b00, "fmsub.s", FINX>;
-defm FNMSUB_S : FPFMA_rrr_frm_m<OPC_NMSUB, 0b00, "fnmsub.s", FINX>;
-defm FNMADD_S : FPFMA_rrr_frm_m<OPC_NMADD, 0b00, "fnmadd.s", FINX>;
-}
-
-let SchedRW = [WriteFAdd32, ReadFAdd32, ReadFAdd32] in {
-defm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", FINX, /*Commutable*/1>;
-defm FSUB_S : FPALU_rr_frm_m<0b0000100, "fsub.s", FINX>;
-}
-let SchedRW = [WriteFMul32, ReadFMul32, ReadFMul32] in
-defm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", FINX, /*Commutable*/1>;
-
-let SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in
-defm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", FINX>;
-
-defm FSQRT_S : FPUnaryOp_r_frm_m<0b0101100, 0b00000, FFINX, "fsqrt.s">,
- Sched<[WriteFSqrt32, ReadFSqrt32]>;
-
-let SchedRW = [WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32],
- mayRaiseFPException = 0 in {
-defm FSGNJ_S : FPALU_rr_m<0b0010000, 0b000, "fsgnj.s", FINX>;
-defm FSGNJN_S : FPALU_rr_m<0b0010000, 0b001, "fsgnjn.s", FINX>;
-defm FSGNJX_S : FPALU_rr_m<0b0010000, 0b010, "fsgnjx.s", FINX>;
-}
-
-let SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in {
-defm FMIN_S : FPALU_rr_m<0b0010100, 0b000, "fmin.s", FINX, /*Commutable*/1>;
-defm FMAX_S : FPALU_rr_m<0b0010100, 0b001, "fmax.s", FINX, /*Commutable*/1>;
-}
-
-let IsSignExtendingOpW = 1 in
-defm FCVT_W_S : FPUnaryOp_r_frm_m<0b1100000, 0b00000, XFINX, "fcvt.w.s">,
- Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
-
-let IsSignExtendingOpW = 1 in
-defm FCVT_WU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00001, XFINX, "fcvt.wu.s">,
- Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
+foreach Ext = FExts in {
+ let SchedRW = [WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32] in {
+ defm FMADD_S : FPFMA_rrr_frm_m<OPC_MADD, 0b00, "fmadd.s", Ext>;
+ defm FMSUB_S : FPFMA_rrr_frm_m<OPC_MSUB, 0b00, "fmsub.s", Ext>;
+ defm FNMSUB_S : FPFMA_rrr_frm_m<OPC_NMSUB, 0b00, "fnmsub.s", Ext>;
+ defm FNMADD_S : FPFMA_rrr_frm_m<OPC_NMADD, 0b00, "fnmadd.s", Ext>;
+ }
+
+ let SchedRW = [WriteFAdd32, ReadFAdd32, ReadFAdd32] in {
+ defm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", Ext, /*Commutable*/1>;
+ defm FSUB_S : FPALU_rr_frm_m<0b0000100, "fsub.s", Ext>;
+ }
+
+ let SchedRW = [WriteFMul32, ReadFMul32, ReadFMul32] in
+ defm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", Ext, /*Commutable*/1>;
+
+ let SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in
+ defm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", Ext>;
+
+ defm FSQRT_S : FPUnaryOp_r_frm_m<0b0101100, 0b00000, Ext, Ext.PrimaryTy,
+ Ext.PrimaryTy, "fsqrt.s">,
+ Sched<[WriteFSqrt32, ReadFSqrt32]>;
+
+ let SchedRW = [WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32],
+ mayRaiseFPException = 0 in {
+ defm FSGNJ_S : FPALU_rr_m<0b0010000, 0b000, "fsgnj.s", Ext>;
+ defm FSGNJN_S : FPALU_rr_m<0b0010000, 0b001, "fsgnjn.s", Ext>;
+ defm FSGNJX_S : FPALU_rr_m<0b0010000, 0b010, "fsgnjx.s", Ext>;
+ }
+
+ let SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in {
+ defm FMIN_S : FPALU_rr_m<0b0010100, 0b000, "fmin.s", Ext, /*Commutable*/1>;
+ defm FMAX_S : FPALU_rr_m<0b0010100, 0b001, "fmax.s", Ext, /*Commutable*/1>;
+ }
+
+ let IsSignExtendingOpW = 1 in
+ defm FCVT_W_S : FPUnaryOp_r_frm_m<0b1100000, 0b00000, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.w.s">,
+ Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
+
+ let IsSignExtendingOpW = 1 in
+ defm FCVT_WU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00001, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.wu.s">,
+ Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>;
+
+ let SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in {
+ defm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", Ext, /*Commutable*/1>;
+ defm FLT_S : FPCmp_rr_m<0b1010000, 0b001, "flt.s", Ext>;
+ defm FLE_S : FPCmp_rr_m<0b1010000, 0b000, "fle.s", Ext>;
+ }
+
+ let mayRaiseFPException = 0 in
+ defm FCLASS_S : FPUnaryOp_r_m<0b1110000, 0b00000, 0b001, Ext, GPR, Ext.PrimaryTy,
+ "fclass.s">,
+ Sched<[WriteFClass32, ReadFClass32]>;
+
+ defm FCVT_S_W : FPUnaryOp_r_frm_m<0b1101000, 0b00000, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.s.w">,
+ Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
+
+ defm FCVT_S_WU : FPUnaryOp_r_frm_m<0b1101000, 0b00001, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.s.wu">,
+ Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
+
+ defm FCVT_L_S : FPUnaryOp_r_frm_m<0b1100000, 0b00010, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.l.s", [IsRV64]>,
+ Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
+
+ defm FCVT_LU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00011, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.lu.s", [IsRV64]>,
+ Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
+
+ defm FCVT_S_L : FPUnaryOp_r_frm_m<0b1101000, 0b00010, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.s.l", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
+
+ defm FCVT_S_LU : FPUnaryOp_r_frm_m<0b1101000, 0b00011, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.s.lu", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
+} // foreach Ext = FExts
let Predicates = [HasStdExtF], mayRaiseFPException = 0,
IsSignExtendingOpW = 1 in
def FMV_X_W : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR32, "fmv.x.w">,
Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>;
-let SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in {
-defm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", FINX, /*Commutable*/1>;
-defm FLT_S : FPCmp_rr_m<0b1010000, 0b001, "flt.s", FINX>;
-defm FLE_S : FPCmp_rr_m<0b1010000, 0b000, "fle.s", FINX>;
-}
-
-let mayRaiseFPException = 0 in
-defm FCLASS_S : FPUnaryOp_r_m<0b1110000, 0b00000, 0b001, XFINX, "fclass.s">,
- Sched<[WriteFClass32, ReadFClass32]>;
-
-defm FCVT_S_W : FPUnaryOp_r_frm_m<0b1101000, 0b00000, FXINX, "fcvt.s.w">,
- Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
-
-defm FCVT_S_WU : FPUnaryOp_r_frm_m<0b1101000, 0b00001, FXINX, "fcvt.s.wu">,
- Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>;
-
let Predicates = [HasStdExtF], mayRaiseFPException = 0 in
def FMV_W_X : FPUnaryOp_r<0b1111000, 0b00000, 0b000, FPR32, GPR, "fmv.w.x">,
Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>;
-defm FCVT_L_S : FPUnaryOp_r_frm_m<0b1100000, 0b00010, XFINX, "fcvt.l.s", [IsRV64]>,
- Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
-
-defm FCVT_LU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00011, XFINX, "fcvt.lu.s", [IsRV64]>,
- Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>;
-
-defm FCVT_S_L : FPUnaryOp_r_frm_m<0b1101000, 0b00010, FXINX, "fcvt.s.l", [IsRV64]>,
- Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
-
-defm FCVT_S_LU : FPUnaryOp_r_frm_m<0b1101000, 0b00011, FXINX, "fcvt.s.lu", [IsRV64]>,
- Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>;
-
//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
//===----------------------------------------------------------------------===//
RVInst Inst>
: Pat<(OpNode Ty:$rs1, Ty:$rs2, Cond), (Inst $rs1, $rs2)>;
multiclass PatSetCC_m<SDPatternOperator OpNode, CondCode Cond,
- RVInst Inst, list<ExtInfo_r> Exts> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates in
- def Ext.Suffix : PatSetCC<Ext.Reg, OpNode, Cond,
- !cast<RVInst>(Inst#Ext.Suffix)>;
+ RVInst Inst, ExtInfo Ext> {
+ let Predicates = Ext.Predicates in
+ def Ext.Suffix : PatSetCC<Ext.PrimaryTy, OpNode, Cond,
+ !cast<RVInst>(Inst#Ext.Suffix)>;
}
class PatFprFpr<SDPatternOperator OpNode, RVInstR Inst,
DAGOperand RegTy>
: Pat<(OpNode RegTy:$rs1, RegTy:$rs2), (Inst $rs1, $rs2)>;
multiclass PatFprFpr_m<SDPatternOperator OpNode, RVInstR Inst,
- list<ExtInfo_r> Exts> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates in
- def Ext.Suffix : PatFprFpr<OpNode, !cast<RVInstR>(Inst#Ext.Suffix),
- Ext.Reg>;
+ ExtInfo Ext> {
+ let Predicates = Ext.Predicates in
+ def Ext.Suffix : PatFprFpr<OpNode, !cast<RVInstR>(Inst#Ext.Suffix),
+ Ext.PrimaryTy>;
}
class PatFprFprDynFrm<SDPatternOperator OpNode, RVInstRFrm Inst,
DAGOperand RegTy>
: Pat<(OpNode RegTy:$rs1, RegTy:$rs2), (Inst $rs1, $rs2, FRM_DYN)>;
multiclass PatFprFprDynFrm_m<SDPatternOperator OpNode, RVInstRFrm Inst,
- list<ExtInfo_r> Exts> {
- foreach Ext = Exts in
- let Predicates = Ext.Predicates in
- def Ext.Suffix : PatFprFprDynFrm<OpNode,
- !cast<RVInstRFrm>(Inst#Ext.Suffix),
- Ext.Reg>;
+ ExtInfo Ext> {
+ let Predicates = Ext.Predicates in
+ def Ext.Suffix : PatFprFprDynFrm<OpNode,
+ !cast<RVInstRFrm>(Inst#Ext.Suffix),
+ Ext.PrimaryTy>;
}
/// Float conversion operations
// are defined later.
/// Float arithmetic operations
-defm : PatFprFprDynFrm_m<any_fadd, FADD_S, FINX>;
-defm : PatFprFprDynFrm_m<any_fsub, FSUB_S, FINX>;
-defm : PatFprFprDynFrm_m<any_fmul, FMUL_S, FINX>;
-defm : PatFprFprDynFrm_m<any_fdiv, FDIV_S, FINX>;
+foreach Ext = FExts in {
+ defm : PatFprFprDynFrm_m<any_fadd, FADD_S, Ext>;
+ defm : PatFprFprDynFrm_m<any_fsub, FSUB_S, Ext>;
+ defm : PatFprFprDynFrm_m<any_fmul, FMUL_S, Ext>;
+ defm : PatFprFprDynFrm_m<any_fdiv, FDIV_S, Ext>;
+}
let Predicates = [HasStdExtF] in {
def : Pat<(any_fsqrt FPR32:$rs1), (FSQRT_S FPR32:$rs1, FRM_DYN)>;
def : Pat<(riscv_fpclass FPR32INX:$rs1), (FCLASS_S_INX $rs1)>;
} // Predicates = [HasStdExtZfinx]
-defm : PatFprFpr_m<fcopysign, FSGNJ_S, FINX>;
+foreach Ext = FExts in
+defm : PatFprFpr_m<fcopysign, FSGNJ_S, Ext>;
let Predicates = [HasStdExtF] in {
def : Pat<(fcopysign FPR32:$rs1, (fneg FPR32:$rs2)), (FSGNJN_S $rs1, $rs2)>;
// The ratified 20191213 ISA spec defines fmin and fmax in a way that matches
// LLVM's fminnum and fmaxnum
// <https://github.com/riscv/riscv-isa-manual/commit/cd20cee7efd9bac7c5aa127ec3b451749d2b3cce>.
-defm : PatFprFpr_m<fminnum, FMIN_S, FINX>;
-defm : PatFprFpr_m<fmaxnum, FMAX_S, FINX>;
+foreach Ext = FExts in {
+ defm : PatFprFpr_m<fminnum, FMIN_S, Ext>;
+ defm : PatFprFpr_m<fmaxnum, FMAX_S, Ext>;
+}
/// Setcc
// FIXME: SETEQ/SETLT/SETLE imply nonans, can we pick better instructions for
// strict versions of those.
// Match non-signaling FEQ_S
-defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_S, FINX>;
-defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_S, FINX>;
-defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_S, FINX>;
-defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_S, FINX>;
-defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_S, FINX>;
-defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_S, FINX>;
+foreach Ext = FExts in {
+ defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_S, Ext>;
+ defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_S, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_S, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_S, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_S, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_S, Ext>;
+}
let Predicates = [HasStdExtF] in {
// Match signaling FEQ_S
(FLE_S_INX $rs1, $rs1)>;
} // Predicates = [HasStdExtZfinx]
-defm : PatSetCC_m<any_fsetccs, SETLT, FLT_S, FINX>;
-defm : PatSetCC_m<any_fsetccs, SETOLT, FLT_S, FINX>;
-defm : PatSetCC_m<any_fsetccs, SETLE, FLE_S, FINX>;
-defm : PatSetCC_m<any_fsetccs, SETOLE, FLE_S, FINX>;
+foreach Ext = FExts in {
+ defm : PatSetCC_m<any_fsetccs, SETLT, FLT_S, Ext>;
+ defm : PatSetCC_m<any_fsetccs, SETOLT, FLT_S, Ext>;
+ defm : PatSetCC_m<any_fsetccs, SETLE, FLE_S, Ext>;
+ defm : PatSetCC_m<any_fsetccs, SETOLE, FLE_S, Ext>;
+}
let Predicates = [HasStdExtF] in {
defm Select_FPR32 : SelectCC_GPR_rrirr<FPR32>;
let DecoderMethod = "DecodeGPRRegisterClass";
}
-def ZfhExt : ExtInfo<0, [HasStdExtZfh]>;
-def ZfhminExt : ExtInfo<0, [HasStdExtZfhOrZfhmin]>;
-def ZhinxExt : ExtInfo<1, [HasStdExtZhinx]>;
-def ZhinxminExt : ExtInfo<1, [HasStdExtZhinxOrZhinxmin]>;
-
-def ZfhminDExt : ExtInfo<0, [HasStdExtZfhOrZfhmin, HasStdExtD]>;
-def ZhinxminZdinxExt : ExtInfo<1, [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64]>;
-def ZhinxminZdinx32Ext : ExtInfo<2, [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32]>;
-
-def H : ExtInfo_r<ZfhExt, FPR16>;
-def H_INX : ExtInfo_r<ZhinxExt, FPR16INX>;
-
-def HH : ExtInfo_rr<ZfhExt, FPR16, FPR16>;
-def HH_INX : ExtInfo_rr<ZhinxExt, FPR16INX, FPR16INX>;
-def XH : ExtInfo_rr<ZfhExt, GPR, FPR16>;
-def XH_INX : ExtInfo_rr<ZhinxExt, GPR, FPR16INX>;
-def HX : ExtInfo_rr<ZfhExt, FPR16, GPR>;
-def HX_INX : ExtInfo_rr<ZhinxExt, FPR16INX, GPR>;
-def HFmin : ExtInfo_rr<ZfhminExt, FPR16, FPR32>;
-def HF_INXmin : ExtInfo_rr<ZhinxminExt, FPR16INX, FPR32INX>;
-def HF_INX : ExtInfo_rr<ZhinxExt, FPR16INX, FPR32INX>;
-def FHmin : ExtInfo_rr<ZfhminExt, FPR32, FPR16>;
-def FH_INXmin : ExtInfo_rr<ZhinxminExt, FPR32INX, FPR16INX>;
-def FH_INX : ExtInfo_rr<ZhinxExt, FPR32INX, FPR16INX>;
-def DHmin : ExtInfo_rr<ZfhminDExt, FPR64, FPR16>;
-def DH_INXmin : ExtInfo_rr<ZhinxminZdinxExt, FPR64INX, FPR16INX>;
-def DH_INX32min : ExtInfo_rr<ZhinxminZdinx32Ext, FPR64IN32X, FPR16INX>;
-def HDmin : ExtInfo_rr<ZfhminDExt, FPR16, FPR64>;
-def HD_INXmin : ExtInfo_rr<ZhinxminZdinxExt, FPR16INX, FPR64INX>;
-def HD_INX32min : ExtInfo_rr<ZhinxminZdinx32Ext, FPR16INX, FPR64IN32X>;
-
-defvar HINX = [H, H_INX];
-defvar HHINX = [HH, HH_INX];
-defvar XHINX = [XH, XH_INX];
-defvar HXINX = [HX, HX_INX];
-defvar HFINXmin = [HFmin, HF_INXmin];
-defvar FHINXmin = [FHmin, FH_INXmin];
-defvar DHINXmin = [DHmin, DH_INXmin, DH_INX32min];
-defvar HDINXmin = [HDmin, HD_INXmin, HD_INX32min];
+def ZfhExt : ExtInfo<"", "", [HasStdExtZfh],
+ FPR16, FPR32, ?, FPR16>;
+def ZfhminExt : ExtInfo<"", "", [HasStdExtZfhOrZfhmin],
+ FPR16, FPR32, ?, FPR16>;
+def ZfhDExt : ExtInfo<"", "", [HasStdExtZfh, HasStdExtD],
+ ?, FPR32, FPR64, FPR16>;
+def ZfhminDExt : ExtInfo<"", "", [HasStdExtZfhOrZfhmin, HasStdExtD],
+ ?, FPR32, FPR64, FPR16>;
+
+def ZhinxExt : ExtInfo<"_INX", "RVZfinx",
+ [HasStdExtZhinx],
+ FPR16INX, FPR32INX, ?, FPR16INX>;
+def ZhinxminExt : ExtInfo<"_INX", "RVZfinx",
+ [HasStdExtZhinxOrZhinxmin],
+ FPR16INX, FPR32INX, ?, FPR16INX>;
+def ZhinxZdinxExt : ExtInfo<"_INX", "RVZfinx",
+ [HasStdExtZhinx, HasStdExtZdinx, IsRV64],
+ ?, FPR32INX, FPR64INX, FPR16INX>;
+def ZhinxminZdinxExt : ExtInfo<"_INX", "RVZfinx",
+ [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64],
+ ?, FPR32INX, FPR64INX, FPR16INX>;
+def ZhinxZdinx32Ext : ExtInfo<"_IN32X", "RV32Zdinx",
+ [HasStdExtZhinx, HasStdExtZdinx, IsRV32],
+ ?, FPR32INX, FPR64IN32X, FPR16INX >;
+def ZhinxminZdinx32Ext : ExtInfo<"_IN32X", "RV32Zdinx",
+ [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32],
+ ?, FPR32INX, FPR64IN32X, FPR16INX>;
+
+defvar ZfhExts = [ZfhExt, ZhinxExt];
+defvar ZfhminExts = [ZfhminExt, ZhinxminExt];
+defvar ZfhDExts = [ZfhDExt, ZhinxZdinxExt, ZhinxZdinx32Ext];
+defvar ZfhminDExts = [ZfhminDExt, ZhinxminZdinxExt, ZhinxminZdinx32Ext];
//===----------------------------------------------------------------------===//
// Instructions
def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>;
} // Predicates = [HasHalfFPLoadStoreMove]
-let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in {
-defm FMADD_H : FPFMA_rrr_frm_m<OPC_MADD, 0b10, "fmadd.h", HINX>;
-defm FMSUB_H : FPFMA_rrr_frm_m<OPC_MSUB, 0b10, "fmsub.h", HINX>;
-defm FNMSUB_H : FPFMA_rrr_frm_m<OPC_NMSUB, 0b10, "fnmsub.h", HINX>;
-defm FNMADD_H : FPFMA_rrr_frm_m<OPC_NMADD, 0b10, "fnmadd.h", HINX>;
-}
-
-let SchedRW = [WriteFAdd16, ReadFAdd16, ReadFAdd16] in {
-defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", HINX, /*Commutable*/1>;
-defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", HINX>;
-}
-let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in
-defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", HINX, /*Commutable*/1>;
-
-let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in
-defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", HINX>;
-
-defm FSQRT_H : FPUnaryOp_r_frm_m<0b0101110, 0b00000, HHINX, "fsqrt.h">,
- Sched<[WriteFSqrt16, ReadFSqrt16]>;
-
-let SchedRW = [WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16],
- mayRaiseFPException = 0 in {
-defm FSGNJ_H : FPALU_rr_m<0b0010010, 0b000, "fsgnj.h", HINX>;
-defm FSGNJN_H : FPALU_rr_m<0b0010010, 0b001, "fsgnjn.h", HINX>;
-defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", HINX>;
-}
-
-let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
-defm FMIN_H : FPALU_rr_m<0b0010110, 0b000, "fmin.h", HINX, /*Commutable*/1>;
-defm FMAX_H : FPALU_rr_m<0b0010110, 0b001, "fmax.h", HINX, /*Commutable*/1>;
-}
-
-let IsSignExtendingOpW = 1 in
-defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, XHINX, "fcvt.w.h">,
- Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
-
-let IsSignExtendingOpW = 1 in
-defm FCVT_WU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00001, XHINX, "fcvt.wu.h">,
- Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
-
-defm FCVT_H_W : FPUnaryOp_r_frm_m<0b1101010, 0b00000, HXINX, "fcvt.h.w">,
- Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
-
-defm FCVT_H_WU : FPUnaryOp_r_frm_m<0b1101010, 0b00001, HXINX, "fcvt.h.wu">,
- Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
-
-defm FCVT_H_S : FPUnaryOp_r_frm_m<0b0100010, 0b00000, HFINXmin, "fcvt.h.s">,
- Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
-
-defm FCVT_S_H : FPUnaryOp_r_m<0b0100000, 0b00010, 0b000, FHINXmin, "fcvt.s.h">,
- Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
+foreach Ext = ZfhExts in {
+ let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in {
+ defm FMADD_H : FPFMA_rrr_frm_m<OPC_MADD, 0b10, "fmadd.h", Ext>;
+ defm FMSUB_H : FPFMA_rrr_frm_m<OPC_MSUB, 0b10, "fmsub.h", Ext>;
+ defm FNMSUB_H : FPFMA_rrr_frm_m<OPC_NMSUB, 0b10, "fnmsub.h", Ext>;
+ defm FNMADD_H : FPFMA_rrr_frm_m<OPC_NMADD, 0b10, "fnmadd.h", Ext>;
+ }
+
+ let SchedRW = [WriteFAdd16, ReadFAdd16, ReadFAdd16] in {
+ defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", Ext, /*Commutable*/1>;
+ defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", Ext>;
+ }
+ let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in
+ defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", Ext, /*Commutable*/1>;
+
+ let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in
+ defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", Ext>;
+
+ defm FSQRT_H : FPUnaryOp_r_frm_m<0b0101110, 0b00000, Ext, Ext.PrimaryTy,
+ Ext.PrimaryTy, "fsqrt.h">,
+ Sched<[WriteFSqrt16, ReadFSqrt16]>;
+
+ let SchedRW = [WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16],
+ mayRaiseFPException = 0 in {
+ defm FSGNJ_H : FPALU_rr_m<0b0010010, 0b000, "fsgnj.h", Ext>;
+ defm FSGNJN_H : FPALU_rr_m<0b0010010, 0b001, "fsgnjn.h", Ext>;
+ defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", Ext>;
+ }
+
+ let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
+ defm FMIN_H : FPALU_rr_m<0b0010110, 0b000, "fmin.h", Ext, /*Commutable*/1>;
+ defm FMAX_H : FPALU_rr_m<0b0010110, 0b001, "fmax.h", Ext, /*Commutable*/1>;
+ }
+
+ let IsSignExtendingOpW = 1 in
+ defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.w.h">,
+ Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
+
+ let IsSignExtendingOpW = 1 in
+ defm FCVT_WU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00001, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.wu.h">,
+ Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
+
+ defm FCVT_H_W : FPUnaryOp_r_frm_m<0b1101010, 0b00000, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.h.w">,
+ Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
+
+ defm FCVT_H_WU : FPUnaryOp_r_frm_m<0b1101010, 0b00001, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.h.wu">,
+ Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
+} // foreach Ext = ZfhExts
+
+foreach Ext = ZfhminExts in {
+ defm FCVT_H_S : FPUnaryOp_r_frm_m<0b0100010, 0b00000, Ext, Ext.PrimaryTy,
+ Ext.F32Ty, "fcvt.h.s">,
+ Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
+
+ defm FCVT_S_H : FPUnaryOp_r_m<0b0100000, 0b00010, 0b000, Ext, Ext.F32Ty,
+ Ext.PrimaryTy, "fcvt.s.h">,
+ Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
+} // foreach Ext = ZfhminExts
let Predicates = [HasHalfFPLoadStoreMove] in {
let mayRaiseFPException = 0, IsSignExtendingOpW = 1 in
Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>;
} // Predicates = [HasHalfFPLoadStoreMove]
-let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
-defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", HINX, /*Commutable*/1>;
-defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", HINX>;
-defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", HINX>;
-}
-
-let mayRaiseFPException = 0 in
-defm FCLASS_H : FPUnaryOp_r_m<0b1110010, 0b00000, 0b001, XHINX, "fclass.h">,
- Sched<[WriteFClass16, ReadFClass16]>;
-
-defm FCVT_L_H : FPUnaryOp_r_frm_m<0b1100010, 0b00010, XHINX, "fcvt.l.h", [IsRV64]>,
- Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
-
-defm FCVT_LU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00011, XHINX, "fcvt.lu.h", [IsRV64]>,
- Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
-
-defm FCVT_H_L : FPUnaryOp_r_frm_m<0b1101010, 0b00010, HXINX, "fcvt.h.l", [IsRV64]>,
- Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
-
-defm FCVT_H_LU : FPUnaryOp_r_frm_m<0b1101010, 0b00011, HXINX, "fcvt.h.lu", [IsRV64]>,
- Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
-
-defm FCVT_H_D : FPUnaryOp_r_frm_m<0b0100010, 0b00001, HDINXmin, "fcvt.h.d">,
- Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
-
-defm FCVT_D_H : FPUnaryOp_r_m<0b0100001, 0b00010, 0b000, DHINXmin, "fcvt.d.h">,
- Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
+foreach Ext = ZfhExts in {
+ let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
+ defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", Ext, /*Commutable*/1>;
+ defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", Ext>;
+ defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", Ext>;
+ }
+
+ let mayRaiseFPException = 0 in
+ defm FCLASS_H : FPUnaryOp_r_m<0b1110010, 0b00000, 0b001, Ext, GPR, Ext.PrimaryTy,
+ "fclass.h">,
+ Sched<[WriteFClass16, ReadFClass16]>;
+
+ defm FCVT_L_H : FPUnaryOp_r_frm_m<0b1100010, 0b00010, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.l.h", [IsRV64]>,
+ Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
+
+ defm FCVT_LU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00011, Ext, GPR, Ext.PrimaryTy,
+ "fcvt.lu.h", [IsRV64]>,
+ Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
+
+ defm FCVT_H_L : FPUnaryOp_r_frm_m<0b1101010, 0b00010, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.h.l", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
+
+ defm FCVT_H_LU : FPUnaryOp_r_frm_m<0b1101010, 0b00011, Ext, Ext.PrimaryTy, GPR,
+ "fcvt.h.lu", [IsRV64]>,
+ Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
+} // foreach Ext = ZfhExts
+
+foreach Ext = ZfhminDExts in {
+ defm FCVT_H_D : FPUnaryOp_r_frm_m<0b0100010, 0b00001, Ext, Ext.F16Ty,
+ Ext.F64Ty, "fcvt.h.d">,
+ Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
+
+ defm FCVT_D_H : FPUnaryOp_r_m<0b0100001, 0b00010, 0b000, Ext, Ext.F64Ty,
+ Ext.F16Ty, "fcvt.d.h">,
+ Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
+} // foreach Ext = ZfhminDExts
//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
// The ratified 20191213 ISA spec defines fmin and fmax in a way that matches
// LLVM's fminnum and fmaxnum
// <https://github.com/riscv/riscv-isa-manual/commit/cd20cee7efd9bac7c5aa127ec3b451749d2b3cce>.
-defm : PatFprFpr_m<fminnum, FMIN_H, HINX>;
-defm : PatFprFpr_m<fmaxnum, FMAX_H, HINX>;
+foreach Ext = ZfhExts in {
+ defm : PatFprFpr_m<fminnum, FMIN_H, Ext>;
+ defm : PatFprFpr_m<fmaxnum, FMAX_H, Ext>;
+}
/// Setcc
// FIXME: SETEQ/SETLT/SETLE imply nonans, can we pick better instructions for
// strict versions of those.
// Match non-signaling FEQ_D
-defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_H, HINX>;
-defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_H, HINX>;
-defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_H, HINX>;
-defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_H, HINX>;
-defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_H, HINX>;
-defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_H, HINX>;
+foreach Ext = ZfhExts in {
+ defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_H, Ext>;
+ defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_H, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_H, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_H, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_H, Ext>;
+ defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_H, Ext>;
+}
let Predicates = [HasStdExtZfh] in {
// Match signaling FEQ_H
(FLE_H_INX $rs1, $rs1)>;
} // Predicates = [HasStdExtZhinx]
-defm : PatSetCC_m<any_fsetccs, SETLT, FLT_H, HINX>;
-defm : PatSetCC_m<any_fsetccs, SETOLT, FLT_H, HINX>;
-defm : PatSetCC_m<any_fsetccs, SETLE, FLE_H, HINX>;
-defm : PatSetCC_m<any_fsetccs, SETOLE, FLE_H, HINX>;
+foreach Ext = ZfhExts in {
+ defm : PatSetCC_m<any_fsetccs, SETLT, FLT_H, Ext>;
+ defm : PatSetCC_m<any_fsetccs, SETOLT, FLT_H, Ext>;
+ defm : PatSetCC_m<any_fsetccs, SETLE, FLE_H, Ext>;
+ defm : PatSetCC_m<any_fsetccs, SETOLE, FLE_H, Ext>;
+}
let Predicates = [HasStdExtZfh] in {
defm Select_FPR16 : SelectCC_GPR_rrirr<FPR16>;