[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfoZfa.td
blob6f88ff7f7ac19af49896bf0e1471cc65c16a2d5e
1 //===-- RISCVInstrInfoZfa.td - RISC-V 'Zfa' instructions ---*- tablegen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the RISC-V instructions from the standard 'Zfa'
10 // additional floating-point extension, version 1.0.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Operand and SDNode transformation definitions.
16 //===----------------------------------------------------------------------===//
18 // 5-bit floating-point immediate encodings.
19 def LoadFPImmOperand : AsmOperandClass {
20   let Name = "LoadFPImm";
21   let ParserMethod = "parseFPImm";
22   let RenderMethod = "addFPImmOperands";
23   let DiagnosticType = "InvalidLoadFPImm";
26 def loadfpimm : Operand<XLenVT> {
27   let ParserMatchClass = LoadFPImmOperand;
28   let PrintMethod = "printFPImmOperand";
31 def RTZArg : AsmOperandClass {
32   let Name = "RTZArg";
33   let RenderMethod = "addFRMArgOperands";
34   let DiagnosticType = "InvalidRTZArg";
35   let ParserMethod = "parseFRMArg";
38 def rtzarg : Operand<XLenVT> {
39   let ParserMatchClass = RTZArg;
40   let PrintMethod = "printFRMArg";
41   let DecoderMethod = "decodeFRMArg";
44 //===----------------------------------------------------------------------===//
45 // Instruction class templates
46 //===----------------------------------------------------------------------===//
48 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
49 class FPBinaryOp_rr<bits<7> funct7, bits<3> funct3, DAGOperand rdty,
50                     DAGOperand rsty, string opcodestr>
51     : RVInstR<funct7, funct3, OPC_OP_FP, (outs rdty:$rd),
52               (ins rsty:$rs1, rsty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
54 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
55 class FPFLI_r<bits<7> funct7, bits<5> rs2val, bits<3> funct3,
56               DAGOperand rdty, string opcodestr>
57     : RVInstR<funct7, funct3, OPC_OP_FP, (outs rdty:$rd),
58               (ins loadfpimm:$imm), opcodestr, "$rd, $imm"> {
59   bits<5> imm;
61   let rs2 = rs2val;
62   let rs1 = imm;
65 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
66     UseNamedOperandTable = 1, hasPostISelHook = 1 in
67 class FPUnaryOp_r_rtz<bits<7> funct7, bits<5> rs2val, DAGOperand rdty,
68                       DAGOperand rs1ty, string opcodestr>
69     : RVInstRFrm<funct7, OPC_OP_FP, (outs rdty:$rd),
70                  (ins rs1ty:$rs1, rtzarg:$frm), opcodestr,
71                   "$rd, $rs1$frm"> {
72   let rs2 = rs2val;
75 //===----------------------------------------------------------------------===//
76 // Instructions
77 //===----------------------------------------------------------------------===//
79 let Predicates = [HasStdExtZfa] in {
80 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
81 def FLI_S : FPFLI_r<0b1111000, 0b00001, 0b000, FPR32, "fli.s">,
82             Sched<[WriteFLI32]>;
84 let SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in {
85 def FMINM_S: FPALU_rr<0b0010100, 0b010, "fminm.s", FPR32, Commutable=1>;
86 def FMAXM_S: FPALU_rr<0b0010100, 0b011, "fmaxm.s", FPR32, Commutable=1>;
89 def FROUND_S : FPUnaryOp_r_frm<0b0100000, 0b00100, FPR32, FPR32, "fround.s">,
90                Sched<[WriteFRoundF32, ReadFRoundF32]>;
91 def FROUNDNX_S : FPUnaryOp_r_frm<0b0100000, 0b00101, FPR32, FPR32, "froundnx.s">,
92                  Sched<[WriteFRoundF32, ReadFRoundF32]>;
94 let SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in {
95 def FLTQ_S : FPCmp_rr<0b1010000, 0b101, "fltq.s", FPR32>;
96 def FLEQ_S : FPCmp_rr<0b1010000, 0b100, "fleq.s", FPR32>;
98 } // Predicates = [HasStdExtZfa]
100 let Predicates = [HasStdExtZfa, HasStdExtD] in {
101 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
102 def FLI_D : FPFLI_r<0b1111001, 0b00001, 0b000, FPR64, "fli.d">,
103             Sched<[WriteFLI64]>;
105 let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
106 def FMINM_D: FPALU_rr<0b0010101, 0b010, "fminm.d", FPR64, Commutable=1>;
107 def FMAXM_D: FPALU_rr<0b0010101, 0b011, "fmaxm.d", FPR64, Commutable=1>;
110 def FROUND_D : FPUnaryOp_r_frm<0b0100001, 0b00100, FPR64, FPR64, "fround.d">,
111                Sched<[WriteFRoundF64, ReadFRoundF64]>;
112 def FROUNDNX_D : FPUnaryOp_r_frm<0b0100001, 0b00101, FPR64, FPR64, "froundnx.d">,
113                  Sched<[WriteFRoundF64, ReadFRoundF64]>;
115 let IsSignExtendingOpW = 1 in
116 def FCVTMOD_W_D
117     : FPUnaryOp_r_rtz<0b1100001, 0b01000, GPR, FPR64, "fcvtmod.w.d">,
118       Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
120 let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
121 def FLTQ_D : FPCmp_rr<0b1010001, 0b101, "fltq.d", FPR64>;
122 def FLEQ_D : FPCmp_rr<0b1010001, 0b100, "fleq.d", FPR64>;
124 } // Predicates = [HasStdExtZfa, HasStdExtD]
126 let Predicates = [HasStdExtZfa, HasStdExtD, IsRV32] in {
127 let mayRaiseFPException = 0 in {
128 def FMVH_X_D : FPUnaryOp_r<0b1110001, 0b00001, 0b000, GPR, FPR64, "fmvh.x.d">,
129                Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>;
130 def FMVP_D_X : FPBinaryOp_rr<0b1011001, 0b000, FPR64, GPR, "fmvp.d.x">,
131                Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>;
134 let isCodeGenOnly = 1, mayRaiseFPException = 0 in
135 def FMV_X_W_FPR64 : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR64,
136                                 "fmv.x.w">,
137                     Sched<[WriteFMovF64ToI64, ReadFMovF64ToI64]>;
138 } // Predicates = [HasStdExtZfa, HasStdExtD, IsRV32]
140 let Predicates = [HasStdExtZfa, HasStdExtZfhOrZvfh] in
141 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
142 def FLI_H : FPFLI_r<0b1111010, 0b00001, 0b000, FPR16, "fli.h">,
143             Sched<[WriteFLI16]>;
145 let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
146 let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
147 def FMINM_H: FPALU_rr<0b0010110, 0b010, "fminm.h", FPR16, Commutable=1>;
148 def FMAXM_H: FPALU_rr<0b0010110, 0b011, "fmaxm.h", FPR16, Commutable=1>;
151 def FROUND_H : FPUnaryOp_r_frm<0b0100010, 0b00100, FPR16, FPR16, "fround.h">,
152                Sched<[WriteFRoundF16, ReadFRoundF16]>;
153 def FROUNDNX_H : FPUnaryOp_r_frm<0b0100010, 0b00101, FPR16, FPR16, "froundnx.h">,
154                  Sched<[WriteFRoundF16, ReadFRoundF16]>;
156 let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
157 def FLTQ_H : FPCmp_rr<0b1010010, 0b101, "fltq.h", FPR16>;
158 def FLEQ_H : FPCmp_rr<0b1010010, 0b100, "fleq.h", FPR16>;
160 } // Predicates = [HasStdExtZfa, HasStdExtZfh]
162 //===----------------------------------------------------------------------===//
163 // Pseudo-instructions and codegen patterns
164 //===----------------------------------------------------------------------===//
166 let Predicates = [HasStdExtZfa] in {
167 def : InstAlias<"fgtq.s $rd, $rs, $rt",
168                 (FLTQ_S GPR:$rd, FPR32:$rt, FPR32:$rs), 0>;
169 def : InstAlias<"fgeq.s $rd, $rs, $rt",
170                 (FLEQ_S GPR:$rd, FPR32:$rt, FPR32:$rs), 0>;
173 let Predicates = [HasStdExtZfa, HasStdExtD] in {
174 def : InstAlias<"fgtq.d $rd, $rs, $rt",
175                 (FLTQ_D GPR:$rd, FPR64:$rt, FPR64:$rs), 0>;
176 def : InstAlias<"fgeq.d $rd, $rs, $rt",
177                 (FLEQ_D GPR:$rd, FPR64:$rt, FPR64:$rs), 0>;
180 let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
181 def : InstAlias<"fgtq.h $rd, $rs, $rt",
182                 (FLTQ_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
183 def : InstAlias<"fgeq.h $rd, $rs, $rt",
184                 (FLEQ_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
187 //===----------------------------------------------------------------------===//
188 // Codegen patterns
189 //===----------------------------------------------------------------------===//
191 let Predicates = [HasStdExtZfa] in {
192 def: PatFprFpr<fminimum, FMINM_S, FPR32, f32>;
193 def: PatFprFpr<fmaximum, FMAXM_S, FPR32, f32>;
195 // frint rounds according to the current rounding mode and detects
196 // inexact conditions.
197 def: Pat<(any_frint FPR32:$rs1), (FROUNDNX_S FPR32:$rs1, FRM_DYN)>;
199 // fnearbyint is like frint but does not detect inexact conditions.
200 def: Pat<(any_fnearbyint FPR32:$rs1), (FROUND_S FPR32:$rs1, FRM_DYN)>;
202 def: Pat<(any_fround FPR32:$rs1), (FROUND_S FPR32:$rs1, FRM_RMM)>;
203 def: Pat<(any_ffloor FPR32:$rs1), (FROUND_S FPR32:$rs1, FRM_RDN)>;
204 def: Pat<(any_fceil FPR32:$rs1), (FROUND_S FPR32:$rs1, FRM_RUP)>;
205 def: Pat<(any_ftrunc FPR32:$rs1), (FROUND_S FPR32:$rs1, FRM_RTZ)>;
207 def: PatSetCC<FPR32, strict_fsetcc, SETLT, FLTQ_S, f32>;
208 def: PatSetCC<FPR32, strict_fsetcc, SETOLT, FLTQ_S, f32>;
209 def: PatSetCC<FPR32, strict_fsetcc, SETLE, FLEQ_S, f32>;
210 def: PatSetCC<FPR32, strict_fsetcc, SETOLE, FLEQ_S, f32>;
211 } // Predicates = [HasStdExtZfa]
213 let Predicates = [HasStdExtZfa, HasStdExtD] in {
214 def: PatFprFpr<fminimum, FMINM_D, FPR64, f64>;
215 def: PatFprFpr<fmaximum, FMAXM_D, FPR64, f64>;
217 // frint rounds according to the current rounding mode and detects
218 // inexact conditions.
219 def: Pat<(any_frint FPR64:$rs1), (FROUNDNX_D FPR64:$rs1, FRM_DYN)>;
221 // fnearbyint is like frint but does not detect inexact conditions.
222 def: Pat<(any_fnearbyint FPR64:$rs1), (FROUND_D FPR64:$rs1, FRM_DYN)>;
224 def: Pat<(any_fround FPR64:$rs1), (FROUND_D FPR64:$rs1, FRM_RMM)>;
225 def: Pat<(any_froundeven FPR64:$rs1), (FROUND_D FPR64:$rs1, FRM_RNE)>;
226 def: Pat<(any_ffloor FPR64:$rs1), (FROUND_D FPR64:$rs1, FRM_RDN)>;
227 def: Pat<(any_fceil FPR64:$rs1), (FROUND_D FPR64:$rs1, FRM_RUP)>;
228 def: Pat<(any_ftrunc FPR64:$rs1), (FROUND_D FPR64:$rs1, FRM_RTZ)>;
230 def: PatSetCC<FPR64, strict_fsetcc, SETLT, FLTQ_D, f64>;
231 def: PatSetCC<FPR64, strict_fsetcc, SETOLT, FLTQ_D, f64>;
232 def: PatSetCC<FPR64, strict_fsetcc, SETLE, FLEQ_D, f64>;
233 def: PatSetCC<FPR64, strict_fsetcc, SETOLE, FLEQ_D, f64>;
234 } // Predicates = [HasStdExtZfa, HasStdExtD]
236 let Predicates = [HasStdExtZfa, HasStdExtD, IsRV32] in {
237 def : Pat<(RISCVBuildPairF64 GPR:$rs1, GPR:$rs2),
238           (FMVP_D_X GPR:$rs1, GPR:$rs2)>;
241 let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
242 def: PatFprFpr<fminimum, FMINM_H, FPR16, f16>;
243 def: PatFprFpr<fmaximum, FMAXM_H, FPR16, f16>;
245 // frint rounds according to the current rounding mode and detects
246 // inexact conditions.
247 def: Pat<(f16 (any_frint FPR16:$rs1)), (FROUNDNX_H FPR16:$rs1, FRM_DYN)>;
249 // fnearbyint is like frint but does not detect inexact conditions.
250 def: Pat<(f16 (any_fnearbyint FPR16:$rs1)), (FROUND_H FPR16:$rs1, FRM_DYN)>;
252 def: Pat<(f16 (any_fround FPR16:$rs1)), (FROUND_H FPR16:$rs1, FRM_RMM)>;
253 def: Pat<(f16 (any_froundeven FPR16:$rs1)), (FROUND_H FPR16:$rs1, FRM_RNE)>;
254 def: Pat<(f16 (any_ffloor FPR16:$rs1)), (FROUND_H FPR16:$rs1, FRM_RDN)>;
255 def: Pat<(f16 (any_fceil FPR16:$rs1)), (FROUND_H FPR16:$rs1, FRM_RUP)>;
256 def: Pat<(f16 (any_ftrunc FPR16:$rs1)), (FROUND_H FPR16:$rs1, FRM_RTZ)>;
258 def: PatSetCC<FPR16, strict_fsetcc, SETLT, FLTQ_H, f16>;
259 def: PatSetCC<FPR16, strict_fsetcc, SETOLT, FLTQ_H, f16>;
260 def: PatSetCC<FPR16, strict_fsetcc, SETLE, FLEQ_H, f16>;
261 def: PatSetCC<FPR16, strict_fsetcc, SETOLE, FLEQ_H, f16>;
262 } // Predicates = [HasStdExtZfa, HasStdExtZfh]