diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -54,41 +54,15 @@ let ParserMatchClass = GPRPF64AsFPR; } -def DExt : ExtInfo<0, [HasStdExtD]>; -def ZdinxExt : ExtInfo<1, [HasStdExtZdinx, IsRV64]>; -def Zdinx32Ext : ExtInfo<2, [HasStdExtZdinx, IsRV32]>; - -def D : ExtInfo_r; -def D_INX : ExtInfo_r; -def D_IN32X : ExtInfo_r; - -def DD : ExtInfo_rr; -def DD_INX : ExtInfo_rr; -def DD_IN32X : ExtInfo_rr; -def DF : ExtInfo_rr; -def DF_INX : ExtInfo_rr; -def DF_IN32X : ExtInfo_rr; -def DX : ExtInfo_rr; -def DX_INX : ExtInfo_rr; -def DX_IN32X : ExtInfo_rr; -def FD : ExtInfo_rr; -def FD_INX : ExtInfo_rr; -def FD_IN32X : ExtInfo_rr; -def XD : ExtInfo_rr; -def XD_INX : ExtInfo_rr; -def XD_IN32X : ExtInfo_rr; - -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 @@ -103,84 +77,100 @@ def FSD : FPStore_r<0b011, "fsd", FPR64, WriteFST64>; } // Predicates = [HasStdExtD] -let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in { -defm FMADD_D : FPFMA_rrr_frm_m; -defm FMSUB_D : FPFMA_rrr_frm_m; -defm FNMSUB_D : FPFMA_rrr_frm_m; -defm FNMADD_D : FPFMA_rrr_frm_m; -} - -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; + defm FMSUB_D : FPFMA_rrr_frm_m; + defm FNMSUB_D : FPFMA_rrr_frm_m; + defm FNMADD_D : FPFMA_rrr_frm_m; + } + + 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]>; @@ -274,10 +264,12 @@ /// Float arithmetic operations -defm : PatFprFprDynFrm_m; -defm : PatFprFprDynFrm_m; -defm : PatFprFprDynFrm_m; -defm : PatFprFprDynFrm_m; +foreach Ext = DExts in { + defm : PatFprFprDynFrm_m; + defm : PatFprFprDynFrm_m; + defm : PatFprFprDynFrm_m; + defm : PatFprFprDynFrm_m; +} let Predicates = [HasStdExtD] in { def : Pat<(any_fsqrt FPR64:$rs1), (FSQRT_D FPR64:$rs1, FRM_DYN)>; @@ -391,20 +383,24 @@ // The ratified 20191213 ISA spec defines fmin and fmax in a way that matches // LLVM's fminnum and fmaxnum. // . -defm : PatFprFpr_m; -defm : PatFprFpr_m; +foreach Ext = DExts in { + defm : PatFprFpr_m; + defm : PatFprFpr_m; +} /// 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; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; +foreach Ext = DExts in { + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; +} let Predicates = [HasStdExtD] in { // Match signaling FEQ_D diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -86,51 +86,31 @@ let DecoderMethod = "DecodeGPRRegisterClass"; } -// inx = 0 : f, d, zfh, zfhmin -// = 1 : zfinx, zdinx, zhinx, zhinxmin -// = 2 : zdinx_rv32 -class ExtInfo inx, list pres> { - string Suffix = !cond(!eq(inx, 0): "", - !eq(inx, 1): "_INX", - !eq(inx, 2): "_IN32X"); - list Predicates = pres; - string Space = !cond(!eq(inx, 0): "", - !eq(inx, 1): "RVZfinx", - !eq(inx, 2): "RV32Zdinx"); -} - -class ExtInfo_r { - string Suffix = ext.Suffix; - list Predicates = ext.Predicates; - string Space = ext.Space; - DAGOperand Reg = reg; -} - -class ExtInfo_rr { - string Suffix = ext.Suffix; - list 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 predicates, + DAGOperand primaryty, DAGOperand f32ty, DAGOperand f64ty, + DAGOperand f16ty> { + list 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; -def F_INX : ExtInfo_r; +def FExt : ExtInfo<"", "", [HasStdExtF], FPR32, FPR32, ?, ?>; -def FF : ExtInfo_rr; -def FF_INX : ExtInfo_rr; -def FX : ExtInfo_rr; -def FX_INX : ExtInfo_rr; -def XF : ExtInfo_rr; -def XF_INX : ExtInfo_rr; +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 @@ -177,10 +157,9 @@ opcodestr, "$rd, $rs1, $rs2, $rs3$frm">; multiclass FPFMA_rrr_frm_m funct2, - string opcodestr, list Exts> { - foreach Ext = Exts in - let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPFMA_rrr_frm; + string opcodestr, ExtInfo Ext> { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPFMA_rrr_frm; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in @@ -191,10 +170,9 @@ let isCommutable = Commutable; } multiclass FPALU_rr_m funct7, bits<3> funct3, string opcodestr, - list Exts, bit Commutable = 0> { - foreach Ext = Exts in - let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPALU_rr; + ExtInfo Ext, bit Commutable = 0> { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPALU_rr; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, @@ -207,10 +185,9 @@ let isCommutable = Commutable; } multiclass FPALU_rr_frm_m funct7, string opcodestr, - list Exts, bit Commutable = 0> { - foreach Ext = Exts in - let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPALU_rr_frm; + ExtInfo Ext, bit Commutable = 0> { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPALU_rr_frm; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in @@ -221,11 +198,10 @@ let rs2 = rs2val; } multiclass FPUnaryOp_r_m funct7, bits<5> rs2val, bits<3> funct3, - list Exts, string opcodestr> { - foreach Ext = Exts in - let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPUnaryOp_r; + ExtInfo Ext, DAGOperand rdty, DAGOperand rs1ty, + string opcodestr> { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPUnaryOp_r; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, @@ -238,13 +214,12 @@ let rs2 = rs2val; } multiclass FPUnaryOp_r_frm_m funct7, bits<5> rs2val, - list Exts, string opcodestr, - list ExtraPreds = []> { - foreach Ext = Exts in - let Predicates = !listconcat(Ext.Predicates, ExtraPreds), - DecoderNamespace = Ext.Space in - def Ext.Suffix : FPUnaryOp_r_frm; + ExtInfo Ext, DAGOperand rdty, DAGOperand rs1ty, + string opcodestr, list ExtraPreds = []> { + let Predicates = !listconcat(Ext.Predicates, ExtraPreds), + DecoderNamespace = Ext.Space in + def Ext.Suffix : FPUnaryOp_r_frm; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, @@ -256,10 +231,9 @@ let isCommutable = Commutable; } multiclass FPCmp_rr_m funct7, bits<3> funct3, string opcodestr, - list Exts, bit Commutable = 0> { - foreach Ext = Exts in - let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPCmp_rr; + ExtInfo Ext, bit Commutable = 0> { + let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in + def Ext.Suffix : FPCmp_rr; } class PseudoFROUND @@ -285,83 +259,96 @@ def FSW : FPStore_r<0b010, "fsw", FPR32, WriteFST32>; } // Predicates = [HasStdExtF] -let SchedRW = [WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32] in { -defm FMADD_S : FPFMA_rrr_frm_m; -defm FMSUB_S : FPFMA_rrr_frm_m; -defm FNMSUB_S : FPFMA_rrr_frm_m; -defm FNMADD_S : FPFMA_rrr_frm_m; -} - -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; + defm FMSUB_S : FPFMA_rrr_frm_m; + defm FNMSUB_S : FPFMA_rrr_frm_m; + defm FNMADD_S : FPFMA_rrr_frm_m; + } + + 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) //===----------------------------------------------------------------------===// @@ -452,34 +439,31 @@ RVInst Inst> : Pat<(OpNode Ty:$rs1, Ty:$rs2, Cond), (Inst $rs1, $rs2)>; multiclass PatSetCC_m Exts> { - foreach Ext = Exts in - let Predicates = Ext.Predicates in - def Ext.Suffix : PatSetCC(Inst#Ext.Suffix)>; + RVInst Inst, ExtInfo Ext> { + let Predicates = Ext.Predicates in + def Ext.Suffix : PatSetCC(Inst#Ext.Suffix)>; } class PatFprFpr : Pat<(OpNode RegTy:$rs1, RegTy:$rs2), (Inst $rs1, $rs2)>; multiclass PatFprFpr_m Exts> { - foreach Ext = Exts in - let Predicates = Ext.Predicates in - def Ext.Suffix : PatFprFpr(Inst#Ext.Suffix), - Ext.Reg>; + ExtInfo Ext> { + let Predicates = Ext.Predicates in + def Ext.Suffix : PatFprFpr(Inst#Ext.Suffix), + Ext.PrimaryTy>; } class PatFprFprDynFrm : Pat<(OpNode RegTy:$rs1, RegTy:$rs2), (Inst $rs1, $rs2, FRM_DYN)>; multiclass PatFprFprDynFrm_m Exts> { - foreach Ext = Exts in - let Predicates = Ext.Predicates in - def Ext.Suffix : PatFprFprDynFrm(Inst#Ext.Suffix), - Ext.Reg>; + ExtInfo Ext> { + let Predicates = Ext.Predicates in + def Ext.Suffix : PatFprFprDynFrm(Inst#Ext.Suffix), + Ext.PrimaryTy>; } /// Float conversion operations @@ -488,10 +472,12 @@ // are defined later. /// Float arithmetic operations -defm : PatFprFprDynFrm_m; -defm : PatFprFprDynFrm_m; -defm : PatFprFprDynFrm_m; -defm : PatFprFprDynFrm_m; +foreach Ext = FExts in { + defm : PatFprFprDynFrm_m; + defm : PatFprFprDynFrm_m; + defm : PatFprFprDynFrm_m; + defm : PatFprFprDynFrm_m; +} let Predicates = [HasStdExtF] in { def : Pat<(any_fsqrt FPR32:$rs1), (FSQRT_S FPR32:$rs1, FRM_DYN)>; @@ -511,7 +497,8 @@ def : Pat<(riscv_fpclass FPR32INX:$rs1), (FCLASS_S_INX $rs1)>; } // Predicates = [HasStdExtZfinx] -defm : PatFprFpr_m; +foreach Ext = FExts in +defm : PatFprFpr_m; let Predicates = [HasStdExtF] in { def : Pat<(fcopysign FPR32:$rs1, (fneg FPR32:$rs2)), (FSGNJN_S $rs1, $rs2)>; @@ -564,20 +551,24 @@ // The ratified 20191213 ISA spec defines fmin and fmax in a way that matches // LLVM's fminnum and fmaxnum // . -defm : PatFprFpr_m; -defm : PatFprFpr_m; +foreach Ext = FExts in { + defm : PatFprFpr_m; + defm : PatFprFpr_m; +} /// 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; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; +foreach Ext = FExts in { + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; +} let Predicates = [HasStdExtF] in { // Match signaling FEQ_S @@ -609,10 +600,12 @@ (FLE_S_INX $rs1, $rs1)>; } // Predicates = [HasStdExtZfinx] -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; +foreach Ext = FExts in { + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; +} let Predicates = [HasStdExtF] in { defm Select_FPR32 : SelectCC_GPR_rrirr; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td @@ -38,45 +38,38 @@ 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; -def H_INX : ExtInfo_r; - -def HH : ExtInfo_rr; -def HH_INX : ExtInfo_rr; -def XH : ExtInfo_rr; -def XH_INX : ExtInfo_rr; -def HX : ExtInfo_rr; -def HX_INX : ExtInfo_rr; -def HFmin : ExtInfo_rr; -def HF_INXmin : ExtInfo_rr; -def HF_INX : ExtInfo_rr; -def FHmin : ExtInfo_rr; -def FH_INXmin : ExtInfo_rr; -def FH_INX : ExtInfo_rr; -def DHmin : ExtInfo_rr; -def DH_INXmin : ExtInfo_rr; -def DH_INX32min : ExtInfo_rr; -def HDmin : ExtInfo_rr; -def HD_INXmin : ExtInfo_rr; -def HD_INX32min : ExtInfo_rr; - -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 @@ -91,57 +84,68 @@ def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>; } // Predicates = [HasHalfFPLoadStoreMove] -let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16] in { -defm FMADD_H : FPFMA_rrr_frm_m; -defm FMSUB_H : FPFMA_rrr_frm_m; -defm FNMSUB_H : FPFMA_rrr_frm_m; -defm FNMADD_H : FPFMA_rrr_frm_m; -} - -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; + defm FMSUB_H : FPFMA_rrr_frm_m; + defm FNMSUB_H : FPFMA_rrr_frm_m; + defm FNMADD_H : FPFMA_rrr_frm_m; + } + + 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 @@ -153,33 +157,44 @@ 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) @@ -330,20 +345,24 @@ // The ratified 20191213 ISA spec defines fmin and fmax in a way that matches // LLVM's fminnum and fmaxnum // . -defm : PatFprFpr_m; -defm : PatFprFpr_m; +foreach Ext = ZfhExts in { + defm : PatFprFpr_m; + defm : PatFprFpr_m; +} /// 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; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; +foreach Ext = ZfhExts in { + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; +} let Predicates = [HasStdExtZfh] in { // Match signaling FEQ_H @@ -375,10 +394,12 @@ (FLE_H_INX $rs1, $rs1)>; } // Predicates = [HasStdExtZhinx] -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; -defm : PatSetCC_m; +foreach Ext = ZfhExts in { + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; + defm : PatSetCC_m; +} let Predicates = [HasStdExtZfh] in { defm Select_FPR16 : SelectCC_GPR_rrirr;