Skip to content

Commit 95d3fd9

Browse files
committed
[RISCV] Refactor how we create separate instructions for F and Zfinx. NFC
Previously we had a ExtInfo_rr class that was instantiated for every combination of types that can appear together along with their predicates, suffixes, and decoder namespace. This patch replaces this with a new ExtInfo class that contains predicates, suffix, namespace, and the f16, f32, and f64 DAGOperands implied by the predicates. The DAGOperand can be unset if the predicate is not enough to distinquish it. At every instruction instantiation we know whether the operands are GPR, f16, f32, or f64 and can ask the ExtInfo for the relevant DAGOperand. The foreach loops of ExtInfo have been moved out of the classes to be at the top level of the 3 files. This allows the file to pick the f16/f32/f64 DAGOperand per instruction and pass it down to the classes separately from the ExtInfo. The ExtInfo still needs to be passed down to get suffix, predicates, and decoder namespace. Reviewed By: sunshaoce Differential Revision: https://reviews.llvm.org/D152948
1 parent 0356cee commit 95d3fd9

File tree

3 files changed

+421
-411
lines changed

3 files changed

+421
-411
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoD.td

Lines changed: 109 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -54,41 +54,15 @@ def FPR64IN32X : RegisterOperand<GPRPF64> {
5454
let ParserMatchClass = GPRPF64AsFPR;
5555
}
5656

57-
def DExt : ExtInfo<0, [HasStdExtD]>;
58-
def ZdinxExt : ExtInfo<1, [HasStdExtZdinx, IsRV64]>;
59-
def Zdinx32Ext : ExtInfo<2, [HasStdExtZdinx, IsRV32]>;
60-
61-
def D : ExtInfo_r<DExt, FPR64>;
62-
def D_INX : ExtInfo_r<ZdinxExt, FPR64INX>;
63-
def D_IN32X : ExtInfo_r<Zdinx32Ext, FPR64IN32X>;
64-
65-
def DD : ExtInfo_rr<DExt, FPR64, FPR64>;
66-
def DD_INX : ExtInfo_rr<ZdinxExt, FPR64INX, FPR64INX>;
67-
def DD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR64IN32X>;
68-
def DF : ExtInfo_rr<DExt, FPR64, FPR32>;
69-
def DF_INX : ExtInfo_rr<ZdinxExt, FPR64INX, FPR32INX>;
70-
def DF_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, FPR32INX>;
71-
def DX : ExtInfo_rr<DExt, FPR64, GPR>;
72-
def DX_INX : ExtInfo_rr<ZdinxExt, FPR64INX, GPR>;
73-
def DX_IN32X : ExtInfo_rr<Zdinx32Ext, FPR64IN32X, GPR>;
74-
def FD : ExtInfo_rr<DExt, FPR32, FPR64>;
75-
def FD_INX : ExtInfo_rr<ZdinxExt, FPR32INX, FPR64INX>;
76-
def FD_IN32X : ExtInfo_rr<Zdinx32Ext, FPR32INX, FPR64IN32X>;
77-
def XD : ExtInfo_rr<DExt, GPR, FPR64>;
78-
def XD_INX : ExtInfo_rr<ZdinxExt, GPR, FPR64INX>;
79-
def XD_IN32X : ExtInfo_rr<Zdinx32Ext, GPR, FPR64IN32X>;
80-
81-
defvar DINX = [D, D_INX, D_IN32X];
82-
defvar DDINX = [DD, DD_INX, DD_IN32X];
83-
defvar DXINX = [DX, DX_INX, DX_IN32X];
84-
defvar DFINX = [DF, DF_INX, DF_IN32X];
85-
defvar FDINX = [FD, FD_INX, FD_IN32X];
86-
defvar XDINX = [XD, XD_INX, XD_IN32X];
87-
88-
// Lists without the IN32X classes that aren't needed for some RV64-only
89-
// instructions.
90-
defvar DXINXRV64 = [DX, DX_INX];
91-
defvar XDINXRV64 = [XD, XD_INX];
57+
def DExt : ExtInfo<"", "", [HasStdExtD], FPR64, FPR32, FPR64, ?>;
58+
59+
def ZdinxExt : ExtInfo<"_INX", "RVZfinx", [HasStdExtZdinx, IsRV64],
60+
FPR64INX, FPR32INX, FPR64INX, ?>;
61+
def Zdinx32Ext : ExtInfo<"_IN32X", "RV32Zdinx", [HasStdExtZdinx, IsRV32],
62+
FPR64IN32X, FPR32INX, FPR64IN32X, ?>;
63+
64+
defvar DExts = [DExt, ZdinxExt, Zdinx32Ext];
65+
defvar DExtsRV64 = [DExt, ZdinxExt];
9266

9367
//===----------------------------------------------------------------------===//
9468
// Instructions
@@ -103,84 +77,100 @@ def FLD : FPLoad_r<0b011, "fld", FPR64, WriteFLD64>;
10377
def FSD : FPStore_r<0b011, "fsd", FPR64, WriteFST64>;
10478
} // Predicates = [HasStdExtD]
10579

106-
let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in {
107-
defm FMADD_D : FPFMA_rrr_frm_m<OPC_MADD, 0b01, "fmadd.d", DINX>;
108-
defm FMSUB_D : FPFMA_rrr_frm_m<OPC_MSUB, 0b01, "fmsub.d", DINX>;
109-
defm FNMSUB_D : FPFMA_rrr_frm_m<OPC_NMSUB, 0b01, "fnmsub.d", DINX>;
110-
defm FNMADD_D : FPFMA_rrr_frm_m<OPC_NMADD, 0b01, "fnmadd.d", DINX>;
111-
}
112-
113-
let SchedRW = [WriteFAdd64, ReadFAdd64, ReadFAdd64] in {
114-
defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX, /*Commutable*/1>;
115-
defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", DINX>;
116-
}
117-
let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
118-
defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX, /*Commutable*/1>;
119-
120-
let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
121-
defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>;
122-
123-
defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, DDINX, "fsqrt.d">,
124-
Sched<[WriteFSqrt64, ReadFSqrt64]>;
125-
126-
let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64],
127-
mayRaiseFPException = 0 in {
128-
defm FSGNJ_D : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d", DINX>;
129-
defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", DINX>;
130-
defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", DINX>;
131-
}
132-
133-
let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
134-
defm FMIN_D : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX, /*Commutable*/1>;
135-
defm FMAX_D : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX, /*Commutable*/1>;
136-
}
137-
138-
defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, FDINX, "fcvt.s.d">,
139-
Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
140-
141-
defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, DFINX, "fcvt.d.s">,
142-
Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
143-
144-
let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
145-
defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX, /*Commutable*/1>;
146-
defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", DINX>;
147-
defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", DINX>;
148-
}
80+
foreach Ext = DExts in {
81+
let SchedRW = [WriteFMA64, ReadFMA64, ReadFMA64, ReadFMA64] in {
82+
defm FMADD_D : FPFMA_rrr_frm_m<OPC_MADD, 0b01, "fmadd.d", Ext>;
83+
defm FMSUB_D : FPFMA_rrr_frm_m<OPC_MSUB, 0b01, "fmsub.d", Ext>;
84+
defm FNMSUB_D : FPFMA_rrr_frm_m<OPC_NMSUB, 0b01, "fnmsub.d", Ext>;
85+
defm FNMADD_D : FPFMA_rrr_frm_m<OPC_NMADD, 0b01, "fnmadd.d", Ext>;
86+
}
87+
88+
let SchedRW = [WriteFAdd64, ReadFAdd64, ReadFAdd64] in {
89+
defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", Ext, /*Commutable*/1>;
90+
defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", Ext>;
91+
}
92+
let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
93+
defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", Ext, /*Commutable*/1>;
94+
95+
let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
96+
defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", Ext>;
97+
98+
defm FSQRT_D : FPUnaryOp_r_frm_m<0b0101101, 0b00000, Ext, Ext.PrimaryTy,
99+
Ext.PrimaryTy, "fsqrt.d">,
100+
Sched<[WriteFSqrt64, ReadFSqrt64]>;
101+
102+
let SchedRW = [WriteFSGNJ64, ReadFSGNJ64, ReadFSGNJ64],
103+
mayRaiseFPException = 0 in {
104+
defm FSGNJ_D : FPALU_rr_m<0b0010001, 0b000, "fsgnj.d", Ext>;
105+
defm FSGNJN_D : FPALU_rr_m<0b0010001, 0b001, "fsgnjn.d", Ext>;
106+
defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", Ext>;
107+
}
108+
109+
let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
110+
defm FMIN_D : FPALU_rr_m<0b0010101, 0b000, "fmin.d", Ext, /*Commutable*/1>;
111+
defm FMAX_D : FPALU_rr_m<0b0010101, 0b001, "fmax.d", Ext, /*Commutable*/1>;
112+
}
113+
114+
defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, Ext, Ext.F32Ty,
115+
Ext.PrimaryTy, "fcvt.s.d">,
116+
Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>;
117+
118+
defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, Ext, Ext.PrimaryTy,
119+
Ext.F32Ty, "fcvt.d.s">,
120+
Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
121+
122+
let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
123+
defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", Ext, /*Commutable*/1>;
124+
defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", Ext>;
125+
defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", Ext>;
126+
}
127+
128+
let mayRaiseFPException = 0 in
129+
defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, Ext, GPR, Ext.PrimaryTy,
130+
"fclass.d">,
131+
Sched<[WriteFClass64, ReadFClass64]>;
132+
133+
let IsSignExtendingOpW = 1 in
134+
defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, Ext, GPR, Ext.PrimaryTy,
135+
"fcvt.w.d">,
136+
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
149137

150-
let mayRaiseFPException = 0 in
151-
defm FCLASS_D : FPUnaryOp_r_m<0b1110001, 0b00000, 0b001, XDINX, "fclass.d">,
152-
Sched<[WriteFClass64, ReadFClass64]>;
138+
let IsSignExtendingOpW = 1 in
139+
defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, Ext, GPR, Ext.PrimaryTy,
140+
"fcvt.wu.d">,
141+
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
153142

154-
let IsSignExtendingOpW = 1 in
155-
defm FCVT_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b00000, XDINX, "fcvt.w.d">,
156-
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
143+
defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, Ext, Ext.PrimaryTy, GPR,
144+
"fcvt.d.w">,
145+
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
157146

158-
let IsSignExtendingOpW = 1 in
159-
defm FCVT_WU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00001, XDINX, "fcvt.wu.d">,
160-
Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
147+
defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, Ext, Ext.PrimaryTy, GPR,
148+
"fcvt.d.wu">,
149+
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
150+
} // foreach Ext = DExts
161151

162-
defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, DXINX, "fcvt.d.w">,
163-
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
152+
foreach Ext = DExtsRV64 in {
153+
defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, Ext, GPR, Ext.PrimaryTy,
154+
"fcvt.l.d", [IsRV64]>,
155+
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
164156

165-
defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, DXINX, "fcvt.d.wu">,
166-
Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
157+
defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, Ext, GPR, Ext.PrimaryTy,
158+
"fcvt.lu.d", [IsRV64]>,
159+
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
167160

168-
defm FCVT_L_D : FPUnaryOp_r_frm_m<0b1100001, 0b00010, XDINXRV64, "fcvt.l.d", [IsRV64]>,
169-
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
161+
defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, Ext, Ext.PrimaryTy, GPR,
162+
"fcvt.d.l", [IsRV64]>,
163+
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
170164

171-
defm FCVT_LU_D : FPUnaryOp_r_frm_m<0b1100001, 0b00011, XDINXRV64, "fcvt.lu.d", [IsRV64]>,
172-
Sched<[WriteFCvtF64ToI64, ReadFCvtF64ToI64]>;
165+
defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, Ext, Ext.PrimaryTy, GPR,
166+
"fcvt.d.lu", [IsRV64]>,
167+
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
168+
} // foreach Ext = DExts64
173169

174170
let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
175171
def FMV_X_D : FPUnaryOp_r<0b1110001, 0b00000, 0b000, GPR, FPR64, "fmv.x.d">,
176172
Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>;
177173

178-
defm FCVT_D_L : FPUnaryOp_r_frm_m<0b1101001, 0b00010, DXINXRV64, "fcvt.d.l", [IsRV64]>,
179-
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
180-
181-
defm FCVT_D_LU : FPUnaryOp_r_frm_m<0b1101001, 0b00011, DXINXRV64, "fcvt.d.lu", [IsRV64]>,
182-
Sched<[WriteFCvtI64ToF64, ReadFCvtI64ToF64]>;
183-
184174
let Predicates = [HasStdExtD, IsRV64], mayRaiseFPException = 0 in
185175
def FMV_D_X : FPUnaryOp_r<0b1111001, 0b00000, 0b000, FPR64, GPR, "fmv.d.x">,
186176
Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>;
@@ -274,10 +264,12 @@ def : Pat<(any_fpextend FPR32INX:$rs1), (FCVT_D_S_IN32X FPR32INX:$rs1)>;
274264

275265
/// Float arithmetic operations
276266

277-
defm : PatFprFprDynFrm_m<any_fadd, FADD_D, DINX>;
278-
defm : PatFprFprDynFrm_m<any_fsub, FSUB_D, DINX>;
279-
defm : PatFprFprDynFrm_m<any_fmul, FMUL_D, DINX>;
280-
defm : PatFprFprDynFrm_m<any_fdiv, FDIV_D, DINX>;
267+
foreach Ext = DExts in {
268+
defm : PatFprFprDynFrm_m<any_fadd, FADD_D, Ext>;
269+
defm : PatFprFprDynFrm_m<any_fsub, FSUB_D, Ext>;
270+
defm : PatFprFprDynFrm_m<any_fmul, FMUL_D, Ext>;
271+
defm : PatFprFprDynFrm_m<any_fdiv, FDIV_D, Ext>;
272+
}
281273

282274
let Predicates = [HasStdExtD] in {
283275
def : Pat<(any_fsqrt FPR64:$rs1), (FSQRT_D FPR64:$rs1, FRM_DYN)>;
@@ -391,20 +383,24 @@ def : Pat<(fneg (any_fma_nsz FPR64IN32X:$rs1, FPR64IN32X:$rs2, FPR64IN32X:$rs3))
391383
// The ratified 20191213 ISA spec defines fmin and fmax in a way that matches
392384
// LLVM's fminnum and fmaxnum.
393385
// <https://github.com/riscv/riscv-isa-manual/commit/cd20cee7efd9bac7c5aa127ec3b451749d2b3cce>.
394-
defm : PatFprFpr_m<fminnum, FMIN_D, DINX>;
395-
defm : PatFprFpr_m<fmaxnum, FMAX_D, DINX>;
386+
foreach Ext = DExts in {
387+
defm : PatFprFpr_m<fminnum, FMIN_D, Ext>;
388+
defm : PatFprFpr_m<fmaxnum, FMAX_D, Ext>;
389+
}
396390

397391
/// Setcc
398392
// FIXME: SETEQ/SETLT/SETLE imply nonans, can we pick better instructions for
399393
// strict versions of those.
400394

401395
// Match non-signaling FEQ_D
402-
defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_D, DINX>;
403-
defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_D, DINX>;
404-
defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_D, DINX>;
405-
defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_D, DINX>;
406-
defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_D, DINX>;
407-
defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_D, DINX>;
396+
foreach Ext = DExts in {
397+
defm : PatSetCC_m<any_fsetcc, SETEQ, FEQ_D, Ext>;
398+
defm : PatSetCC_m<any_fsetcc, SETOEQ, FEQ_D, Ext>;
399+
defm : PatSetCC_m<strict_fsetcc, SETLT, PseudoQuietFLT_D, Ext>;
400+
defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_D, Ext>;
401+
defm : PatSetCC_m<strict_fsetcc, SETLE, PseudoQuietFLE_D, Ext>;
402+
defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_D, Ext>;
403+
}
408404

409405
let Predicates = [HasStdExtD] in {
410406
// Match signaling FEQ_D

0 commit comments

Comments
 (0)