10b57cec5SDimitry Andric//===-- RISCVInstrInfoF.td - RISC-V 'F' instructions -------*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric// 90b57cec5SDimitry Andric// This file describes the RISC-V instructions from the standard 'F', 100b57cec5SDimitry Andric// Single-Precision Floating-Point instruction set extension. 110b57cec5SDimitry Andric// 120b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric// RISC-V specific DAG Nodes. 160b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 170b57cec5SDimitry Andric 180b57cec5SDimitry Andricdef SDT_RISCVFMV_W_X_RV64 190b57cec5SDimitry Andric : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i64>]>; 200b57cec5SDimitry Andricdef SDT_RISCVFMV_X_ANYEXTW_RV64 210b57cec5SDimitry Andric : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, f32>]>; 220eae32dcSDimitry Andricdef SDT_RISCVFCVT_W_RV64 2304eeddc0SDimitry Andric : SDTypeProfile<1, 2, [SDTCisVT<0, i64>, SDTCisFP<1>, 2404eeddc0SDimitry Andric SDTCisVT<2, i64>]>; 250eae32dcSDimitry Andricdef SDT_RISCVFCVT_X 2604eeddc0SDimitry Andric : SDTypeProfile<1, 2, [SDTCisVT<0, XLenVT>, SDTCisFP<1>, 2704eeddc0SDimitry Andric SDTCisVT<2, XLenVT>]>; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andricdef riscv_fmv_w_x_rv64 300b57cec5SDimitry Andric : SDNode<"RISCVISD::FMV_W_X_RV64", SDT_RISCVFMV_W_X_RV64>; 310b57cec5SDimitry Andricdef riscv_fmv_x_anyextw_rv64 320b57cec5SDimitry Andric : SDNode<"RISCVISD::FMV_X_ANYEXTW_RV64", SDT_RISCVFMV_X_ANYEXTW_RV64>; 3304eeddc0SDimitry Andricdef riscv_fcvt_w_rv64 3404eeddc0SDimitry Andric : SDNode<"RISCVISD::FCVT_W_RV64", SDT_RISCVFCVT_W_RV64>; 3504eeddc0SDimitry Andricdef riscv_fcvt_wu_rv64 3604eeddc0SDimitry Andric : SDNode<"RISCVISD::FCVT_WU_RV64", SDT_RISCVFCVT_W_RV64>; 3704eeddc0SDimitry Andricdef riscv_fcvt_x 3804eeddc0SDimitry Andric : SDNode<"RISCVISD::FCVT_X", SDT_RISCVFCVT_X>; 3904eeddc0SDimitry Andricdef riscv_fcvt_xu 4004eeddc0SDimitry Andric : SDNode<"RISCVISD::FCVT_XU", SDT_RISCVFCVT_X>; 410eae32dcSDimitry Andric 4204eeddc0SDimitry Andricdef riscv_strict_fcvt_w_rv64 4304eeddc0SDimitry Andric : SDNode<"RISCVISD::STRICT_FCVT_W_RV64", SDT_RISCVFCVT_W_RV64, 440eae32dcSDimitry Andric [SDNPHasChain]>; 4504eeddc0SDimitry Andricdef riscv_strict_fcvt_wu_rv64 4604eeddc0SDimitry Andric : SDNode<"RISCVISD::STRICT_FCVT_WU_RV64", SDT_RISCVFCVT_W_RV64, 470eae32dcSDimitry Andric [SDNPHasChain]>; 480eae32dcSDimitry Andric 4904eeddc0SDimitry Andricdef riscv_any_fcvt_w_rv64 : PatFrags<(ops node:$src, node:$frm), 5004eeddc0SDimitry Andric [(riscv_strict_fcvt_w_rv64 node:$src, node:$frm), 5104eeddc0SDimitry Andric (riscv_fcvt_w_rv64 node:$src, node:$frm)]>; 5204eeddc0SDimitry Andricdef riscv_any_fcvt_wu_rv64 : PatFrags<(ops node:$src, node:$frm), 5304eeddc0SDimitry Andric [(riscv_strict_fcvt_wu_rv64 node:$src, node:$frm), 5404eeddc0SDimitry Andric (riscv_fcvt_wu_rv64 node:$src, node:$frm)]>; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 570b57cec5SDimitry Andric// Operand and SDNode transformation definitions. 580b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 590b57cec5SDimitry Andric 60d56accc7SDimitry Andric// Zfinx 61d56accc7SDimitry Andric 62d56accc7SDimitry Andricdef GPRAsFPR : AsmOperandClass { 63d56accc7SDimitry Andric let Name = "GPRAsFPR"; 64d56accc7SDimitry Andric let ParserMethod = "parseGPRAsFPR"; 65d56accc7SDimitry Andric let RenderMethod = "addRegOperands"; 66d56accc7SDimitry Andric} 67d56accc7SDimitry Andric 68d56accc7SDimitry Andricdef FPR32INX : RegisterOperand<GPRF32> { 69d56accc7SDimitry Andric let ParserMatchClass = GPRAsFPR; 70d56accc7SDimitry Andric let DecoderMethod = "DecodeGPRRegisterClass"; 71d56accc7SDimitry Andric} 72d56accc7SDimitry Andric 73d56accc7SDimitry Andric// inx = 0 : f, d, zfh, zfhmin 74d56accc7SDimitry Andric// = 1 : zfinx, zdinx, zhinx, zhinxmin 75d56accc7SDimitry Andric// = 2 : zdinx_rv32 76d56accc7SDimitry Andricclass ExtInfo<bits<2> inx, list<Predicate> pres> { 77d56accc7SDimitry Andric string Suffix = !cond(!eq(inx, 0): "", 78d56accc7SDimitry Andric !eq(inx, 1): "_INX", 79d56accc7SDimitry Andric !eq(inx, 2): "_IN32X"); 80d56accc7SDimitry Andric list<Predicate> Predicates = pres; 81d56accc7SDimitry Andric string Space = !cond(!eq(inx, 0): "", 82d56accc7SDimitry Andric !eq(inx, 1): "RVZfinx", 83d56accc7SDimitry Andric !eq(inx, 2): "RV32Zdinx"); 84d56accc7SDimitry Andric} 85d56accc7SDimitry Andric 86d56accc7SDimitry Andricclass ExtInfo_r<ExtInfo ext, DAGOperand reg> { 87d56accc7SDimitry Andric string Suffix = ext.Suffix; 88d56accc7SDimitry Andric list<Predicate> Predicates = ext.Predicates; 89d56accc7SDimitry Andric string Space = ext.Space; 90d56accc7SDimitry Andric DAGOperand Reg = reg; 91d56accc7SDimitry Andric} 92d56accc7SDimitry Andric 93d56accc7SDimitry Andricclass ExtInfo_rr<ExtInfo ext, DAGOperand rdty, DAGOperand rs1ty> { 94d56accc7SDimitry Andric string Suffix = ext.Suffix; 95d56accc7SDimitry Andric list<Predicate> Predicates = ext.Predicates; 96d56accc7SDimitry Andric string Space = ext.Space; 97d56accc7SDimitry Andric DAGOperand RdTy = rdty; 98d56accc7SDimitry Andric DAGOperand Rs1Ty = rs1ty; 99d56accc7SDimitry Andric} 100d56accc7SDimitry Andric 101d56accc7SDimitry Andricdef FExt : ExtInfo<0, [HasStdExtF]>; 102d56accc7SDimitry Andricdef F64Ext : ExtInfo<0, [HasStdExtF, IsRV64]>; 103d56accc7SDimitry Andricdef ZfinxExt : ExtInfo<1, [HasStdExtZfinx]>; 104d56accc7SDimitry Andricdef Zfinx64Ext : ExtInfo<1, [HasStdExtZfinx, IsRV64]>; 105d56accc7SDimitry Andric 106d56accc7SDimitry Andricdef F : ExtInfo_r<FExt, FPR32>; 107d56accc7SDimitry Andricdef F_INX : ExtInfo_r<ZfinxExt, FPR32INX>; 108d56accc7SDimitry Andric 109d56accc7SDimitry Andricdef FF : ExtInfo_rr<FExt, FPR32, FPR32>; 110d56accc7SDimitry Andricdef FF_INX : ExtInfo_rr<ZfinxExt, FPR32INX, FPR32INX>; 111d56accc7SDimitry Andricdef FX : ExtInfo_rr<FExt, FPR32, GPR>; 112d56accc7SDimitry Andricdef FX_INX : ExtInfo_rr<ZfinxExt, FPR32INX, GPR>; 113d56accc7SDimitry Andricdef FX_64 : ExtInfo_rr<F64Ext, FPR32, GPR>; 114d56accc7SDimitry Andricdef FX_INX_64 : ExtInfo_rr<Zfinx64Ext, FPR32INX, GPR>; 115d56accc7SDimitry Andricdef XF : ExtInfo_rr<FExt, GPR, FPR32>; 116d56accc7SDimitry Andricdef XF_64 : ExtInfo_rr<F64Ext, GPR, FPR32>; 117d56accc7SDimitry Andricdef XF_INX : ExtInfo_rr<ZfinxExt, GPR, FPR32INX>; 118d56accc7SDimitry Andricdef XF_INX_64 : ExtInfo_rr<Zfinx64Ext, GPR, FPR32INX>; 119d56accc7SDimitry Andric 120d56accc7SDimitry Andricdefvar FINX = [F, F_INX]; 121d56accc7SDimitry Andricdefvar FFINX = [FF, FF_INX]; 122d56accc7SDimitry Andricdefvar FXINX = [FX, FX_INX]; 123d56accc7SDimitry Andricdefvar XFINX = [XF, XF_INX]; 124d56accc7SDimitry Andricdefvar XFIN64X = [XF_64, XF_INX_64]; 125d56accc7SDimitry Andricdefvar FXIN64X = [FX_64, FX_INX_64]; 126d56accc7SDimitry Andric 1270b57cec5SDimitry Andric// Floating-point rounding mode 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andricdef FRMArg : AsmOperandClass { 1300b57cec5SDimitry Andric let Name = "FRMArg"; 1310b57cec5SDimitry Andric let RenderMethod = "addFRMArgOperands"; 1320b57cec5SDimitry Andric let DiagnosticType = "InvalidFRMArg"; 1330b57cec5SDimitry Andric} 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andricdef frmarg : Operand<XLenVT> { 1360b57cec5SDimitry Andric let ParserMatchClass = FRMArg; 1370b57cec5SDimitry Andric let PrintMethod = "printFRMArg"; 1380b57cec5SDimitry Andric let DecoderMethod = "decodeFRMArg"; 1390b57cec5SDimitry Andric} 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 1420b57cec5SDimitry Andric// Instruction class templates 1430b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 1440b57cec5SDimitry Andric 14504eeddc0SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 14604eeddc0SDimitry Andricclass FPLoad_r<bits<3> funct3, string opcodestr, RegisterClass rty, 14704eeddc0SDimitry Andric SchedWrite sw> 14804eeddc0SDimitry Andric : RVInstI<funct3, OPC_LOAD_FP, (outs rty:$rd), 14904eeddc0SDimitry Andric (ins GPR:$rs1, simm12:$imm12), 15004eeddc0SDimitry Andric opcodestr, "$rd, ${imm12}(${rs1})">, 15104eeddc0SDimitry Andric Sched<[sw, ReadFMemBase]>; 15204eeddc0SDimitry Andric 15304eeddc0SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 15404eeddc0SDimitry Andricclass FPStore_r<bits<3> funct3, string opcodestr, RegisterClass rty, 15504eeddc0SDimitry Andric SchedWrite sw> 15604eeddc0SDimitry Andric : RVInstS<funct3, OPC_STORE_FP, (outs), 15704eeddc0SDimitry Andric (ins rty:$rs2, GPR:$rs1, simm12:$imm12), 15804eeddc0SDimitry Andric opcodestr, "$rs2, ${imm12}(${rs1})">, 15904eeddc0SDimitry Andric Sched<[sw, ReadStoreData, ReadFMemBase]>; 16004eeddc0SDimitry Andric 1610eae32dcSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, 1620eae32dcSDimitry Andric UseNamedOperandTable = 1, hasPostISelHook = 1 in 1630eae32dcSDimitry Andricclass FPFMA_rrr_frm<RISCVOpcode opcode, bits<2> funct2, string opcodestr, 164d56accc7SDimitry Andric DAGOperand rty> 1650eae32dcSDimitry Andric : RVInstR4Frm<funct2, opcode, (outs rty:$rd), 1660eae32dcSDimitry Andric (ins rty:$rs1, rty:$rs2, rty:$rs3, frmarg:$frm), 1670eae32dcSDimitry Andric opcodestr, "$rd, $rs1, $rs2, $rs3, $frm">; 1680b57cec5SDimitry Andric 169d56accc7SDimitry Andricmulticlass FPFMA_rrr_frm_m<RISCVOpcode opcode, bits<2> funct2, 170d56accc7SDimitry Andric string opcodestr, list<ExtInfo_r> Exts> { 171d56accc7SDimitry Andric foreach Ext = Exts in 172d56accc7SDimitry Andric let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in 173d56accc7SDimitry Andric def Ext.Suffix : FPFMA_rrr_frm<opcode, funct2, opcodestr, Ext.Reg>; 174d56accc7SDimitry Andric} 175d56accc7SDimitry Andric 1760eae32dcSDimitry Andricclass FPFMADynFrmAlias<FPFMA_rrr_frm Inst, string OpcodeStr, 177d56accc7SDimitry Andric DAGOperand rty> 1780b57cec5SDimitry Andric : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", 1790eae32dcSDimitry Andric (Inst rty:$rd, rty:$rs1, rty:$rs2, rty:$rs3, 0b111)>; 180d56accc7SDimitry Andricmulticlass FPFMADynFrmAlias_m<FPFMA_rrr_frm Inst, string OpcodeStr, 181d56accc7SDimitry Andric list<ExtInfo_r> Exts> { 182d56accc7SDimitry Andric foreach Ext = Exts in 183d56accc7SDimitry Andric let Predicates = Ext.Predicates in 184d56accc7SDimitry Andric def : FPFMADynFrmAlias<!cast<FPFMA_rrr_frm>(Inst#Ext.Suffix), OpcodeStr, 185d56accc7SDimitry Andric Ext.Reg>; 186d56accc7SDimitry Andric} 1870b57cec5SDimitry Andric 1880eae32dcSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in 1890eae32dcSDimitry Andricclass FPALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr, 190d56accc7SDimitry Andric DAGOperand rty> 1910eae32dcSDimitry Andric : RVInstR<funct7, funct3, OPC_OP_FP, (outs rty:$rd), 1920eae32dcSDimitry Andric (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2">; 193d56accc7SDimitry Andricmulticlass FPALU_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr, 194d56accc7SDimitry Andric list<ExtInfo_r> Exts> { 195d56accc7SDimitry Andric foreach Ext = Exts in 196d56accc7SDimitry Andric let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in 197d56accc7SDimitry Andric def Ext.Suffix : FPALU_rr<funct7, funct3, opcodestr, Ext.Reg>; 1980eae32dcSDimitry Andric} 1990b57cec5SDimitry Andric 2000eae32dcSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, 2010eae32dcSDimitry Andric UseNamedOperandTable = 1, hasPostISelHook = 1 in 202d56accc7SDimitry Andricclass FPALU_rr_frm<bits<7> funct7, string opcodestr, DAGOperand rty> 203d56accc7SDimitry Andric : RVInstRFrm<funct7, OPC_OP_FP, (outs rty:$rd), 204d56accc7SDimitry Andric (ins rty:$rs1, rty:$rs2, frmarg:$frm), opcodestr, 205d56accc7SDimitry Andric "$rd, $rs1, $rs2, $frm">; 206d56accc7SDimitry Andric 207d56accc7SDimitry Andricmulticlass FPALU_rr_frm_m<bits<7> funct7, string opcodestr, 208d56accc7SDimitry Andric list<ExtInfo_r> Exts> { 209d56accc7SDimitry Andric foreach Ext = Exts in 210d56accc7SDimitry Andric let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in 211d56accc7SDimitry Andric def Ext.Suffix : FPALU_rr_frm<funct7, opcodestr, Ext.Reg>; 212d56accc7SDimitry Andric} 213d56accc7SDimitry Andric 214d56accc7SDimitry Andricclass FPALUDynFrmAlias<FPALU_rr_frm Inst, string OpcodeStr, 215d56accc7SDimitry Andric DAGOperand rty> 216d56accc7SDimitry Andric : InstAlias<OpcodeStr#" $rd, $rs1, $rs2", 217d56accc7SDimitry Andric (Inst rty:$rd, rty:$rs1, rty:$rs2, 0b111)>; 218d56accc7SDimitry Andricmulticlass FPALUDynFrmAlias_m<FPALU_rr_frm Inst, string OpcodeStr, 219d56accc7SDimitry Andric list<ExtInfo_r> Exts> { 220d56accc7SDimitry Andric foreach Ext = Exts in 221d56accc7SDimitry Andric let Predicates = Ext.Predicates in 222d56accc7SDimitry Andric def : FPALUDynFrmAlias<!cast<FPALU_rr_frm>(Inst#Ext.Suffix), OpcodeStr, 223d56accc7SDimitry Andric Ext.Reg>; 224d56accc7SDimitry Andric} 225d56accc7SDimitry Andric 226d56accc7SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in 227d56accc7SDimitry Andricclass FPUnaryOp_r<bits<7> funct7, bits<5> rs2val, bits<3> funct3, 228d56accc7SDimitry Andric DAGOperand rdty, DAGOperand rs1ty, string opcodestr> 229d56accc7SDimitry Andric : RVInstR<funct7, funct3, OPC_OP_FP, (outs rdty:$rd), (ins rs1ty:$rs1), 230d56accc7SDimitry Andric opcodestr, "$rd, $rs1"> { 231d56accc7SDimitry Andric let rs2 = rs2val; 232d56accc7SDimitry Andric} 233d56accc7SDimitry Andricmulticlass FPUnaryOp_r_m<bits<7> funct7, bits<5> rs2val, bits<3> funct3, 234d56accc7SDimitry Andric list<ExtInfo_rr> Exts, string opcodestr> { 235d56accc7SDimitry Andric foreach Ext = Exts in 236d56accc7SDimitry Andric let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in 237d56accc7SDimitry Andric def Ext.Suffix : FPUnaryOp_r<funct7, rs2val, funct3, Ext.RdTy, Ext.Rs1Ty, 238d56accc7SDimitry Andric opcodestr>; 239d56accc7SDimitry Andric} 240d56accc7SDimitry Andric 241d56accc7SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, 242d56accc7SDimitry Andric UseNamedOperandTable = 1, hasPostISelHook = 1 in 243d56accc7SDimitry Andricclass FPUnaryOp_r_frm<bits<7> funct7, bits<5> rs2val, DAGOperand rdty, 244d56accc7SDimitry Andric DAGOperand rs1ty, string opcodestr> 2450b57cec5SDimitry Andric : RVInstRFrm<funct7, OPC_OP_FP, (outs rdty:$rd), 2460eae32dcSDimitry Andric (ins rs1ty:$rs1, frmarg:$frm), opcodestr, 2470eae32dcSDimitry Andric "$rd, $rs1, $frm"> { 2480eae32dcSDimitry Andric let rs2 = rs2val; 2490eae32dcSDimitry Andric} 250d56accc7SDimitry Andricmulticlass FPUnaryOp_r_frm_m<bits<7> funct7, bits<5> rs2val, 251d56accc7SDimitry Andric list<ExtInfo_rr> Exts, string opcodestr> { 252d56accc7SDimitry Andric foreach Ext = Exts in 253d56accc7SDimitry Andric let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in 254d56accc7SDimitry Andric def Ext.Suffix : FPUnaryOp_r_frm<funct7, rs2val, Ext.RdTy, Ext.Rs1Ty, 255d56accc7SDimitry Andric opcodestr>; 256d56accc7SDimitry Andric} 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andricclass FPUnaryOpDynFrmAlias<FPUnaryOp_r_frm Inst, string OpcodeStr, 259d56accc7SDimitry Andric DAGOperand rdty, DAGOperand rs1ty> 2600b57cec5SDimitry Andric : InstAlias<OpcodeStr#" $rd, $rs1", 2610b57cec5SDimitry Andric (Inst rdty:$rd, rs1ty:$rs1, 0b111)>; 262d56accc7SDimitry Andricmulticlass FPUnaryOpDynFrmAlias_m<FPUnaryOp_r_frm Inst, string OpcodeStr, 263d56accc7SDimitry Andric list<ExtInfo_rr> Exts> { 264d56accc7SDimitry Andric foreach Ext = Exts in 265d56accc7SDimitry Andric let Predicates = Ext.Predicates in 266d56accc7SDimitry Andric def : FPUnaryOpDynFrmAlias<!cast<FPUnaryOp_r_frm>(Inst#Ext.Suffix), 267d56accc7SDimitry Andric OpcodeStr, Ext.RdTy, Ext.Rs1Ty>; 268d56accc7SDimitry Andric} 2690b57cec5SDimitry Andric 2700eae32dcSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in 2710eae32dcSDimitry Andricclass FPCmp_rr<bits<7> funct7, bits<3> funct3, string opcodestr, 272d56accc7SDimitry Andric DAGOperand rty> 2730eae32dcSDimitry Andric : RVInstR<funct7, funct3, OPC_OP_FP, (outs GPR:$rd), 2740eae32dcSDimitry Andric (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2">; 275d56accc7SDimitry Andricmulticlass FPCmp_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr, 276d56accc7SDimitry Andric list<ExtInfo_r> Exts> { 277d56accc7SDimitry Andric foreach Ext = Exts in 278d56accc7SDimitry Andric let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in 279d56accc7SDimitry Andric def Ext.Suffix : FPCmp_rr<funct7, funct3, opcodestr, Ext.Reg>; 280d56accc7SDimitry Andric} 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 2830b57cec5SDimitry Andric// Instructions 2840b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andriclet Predicates = [HasStdExtF] in { 28704eeddc0SDimitry Andricdef FLW : FPLoad_r<0b010, "flw", FPR32, WriteFLD32>; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric// Operands for stores are in the order srcreg, base, offset rather than 2900b57cec5SDimitry Andric// reflecting the order these fields are specified in the instruction 2910b57cec5SDimitry Andric// encoding. 29204eeddc0SDimitry Andricdef FSW : FPStore_r<0b010, "fsw", FPR32, WriteFST32>; 293d56accc7SDimitry Andric} // Predicates = [HasStdExtF] 2940b57cec5SDimitry Andric 2950eae32dcSDimitry Andriclet SchedRW = [WriteFMA32, ReadFMA32, ReadFMA32, ReadFMA32] in { 296d56accc7SDimitry Andricdefm FMADD_S : FPFMA_rrr_frm_m<OPC_MADD, 0b00, "fmadd.s", FINX>; 297d56accc7SDimitry Andricdefm FMSUB_S : FPFMA_rrr_frm_m<OPC_MSUB, 0b00, "fmsub.s", FINX>; 298d56accc7SDimitry Andricdefm FNMSUB_S : FPFMA_rrr_frm_m<OPC_NMSUB, 0b00, "fnmsub.s", FINX>; 299d56accc7SDimitry Andricdefm FNMADD_S : FPFMA_rrr_frm_m<OPC_NMADD, 0b00, "fnmadd.s", FINX>; 3000b57cec5SDimitry Andric} 3010eae32dcSDimitry Andric 302d56accc7SDimitry Andricdefm : FPFMADynFrmAlias_m<FMADD_S, "fmadd.s", FINX>; 303d56accc7SDimitry Andricdefm : FPFMADynFrmAlias_m<FMSUB_S, "fmsub.s", FINX>; 304d56accc7SDimitry Andricdefm : FPFMADynFrmAlias_m<FNMSUB_S, "fnmsub.s", FINX>; 305d56accc7SDimitry Andricdefm : FPFMADynFrmAlias_m<FNMADD_S, "fnmadd.s", FINX>; 3060eae32dcSDimitry Andric 307d56accc7SDimitry Andriclet SchedRW = [WriteFALU32, ReadFALU32, ReadFALU32] in { 308d56accc7SDimitry Andricdefm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", FINX>; 309d56accc7SDimitry Andricdefm FSUB_S : FPALU_rr_frm_m<0b0000100, "fsub.s", FINX>; 310d56accc7SDimitry Andric} 311d56accc7SDimitry Andriclet SchedRW = [WriteFMul32, ReadFMul32, ReadFMul32] in 312d56accc7SDimitry Andricdefm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", FINX>; 3130eae32dcSDimitry Andric 314d56accc7SDimitry Andriclet SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in 315d56accc7SDimitry Andricdefm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", FINX>; 3160eae32dcSDimitry Andric 317d56accc7SDimitry Andricdefm : FPALUDynFrmAlias_m<FADD_S, "fadd.s", FINX>; 318d56accc7SDimitry Andricdefm : FPALUDynFrmAlias_m<FSUB_S, "fsub.s", FINX>; 319d56accc7SDimitry Andricdefm : FPALUDynFrmAlias_m<FMUL_S, "fmul.s", FINX>; 320d56accc7SDimitry Andricdefm : FPALUDynFrmAlias_m<FDIV_S, "fdiv.s", FINX>; 321d56accc7SDimitry Andric 322d56accc7SDimitry Andricdefm FSQRT_S : FPUnaryOp_r_frm_m<0b0101100, 0b00000, FFINX, "fsqrt.s">, 3230eae32dcSDimitry Andric Sched<[WriteFSqrt32, ReadFSqrt32]>; 324d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FSQRT_S, "fsqrt.s", FFINX>; 3250b57cec5SDimitry Andric 3260eae32dcSDimitry Andriclet SchedRW = [WriteFSGNJ32, ReadFSGNJ32, ReadFSGNJ32], 3270eae32dcSDimitry Andric mayRaiseFPException = 0 in { 328d56accc7SDimitry Andricdefm FSGNJ_S : FPALU_rr_m<0b0010000, 0b000, "fsgnj.s", FINX>; 329d56accc7SDimitry Andricdefm FSGNJN_S : FPALU_rr_m<0b0010000, 0b001, "fsgnjn.s", FINX>; 330d56accc7SDimitry Andricdefm FSGNJX_S : FPALU_rr_m<0b0010000, 0b010, "fsgnjx.s", FINX>; 3310b57cec5SDimitry Andric} 3320eae32dcSDimitry Andric 3330eae32dcSDimitry Andriclet SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in { 334d56accc7SDimitry Andricdefm FMIN_S : FPALU_rr_m<0b0010100, 0b000, "fmin.s", FINX>; 335d56accc7SDimitry Andricdefm FMAX_S : FPALU_rr_m<0b0010100, 0b001, "fmax.s", FINX>; 3360eae32dcSDimitry Andric} 3370eae32dcSDimitry Andric 338d56accc7SDimitry Andricdefm FCVT_W_S : FPUnaryOp_r_frm_m<0b1100000, 0b00000, XFINX, "fcvt.w.s">, 3390eae32dcSDimitry Andric Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; 340d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_W_S, "fcvt.w.s", XFINX>; 3410b57cec5SDimitry Andric 342d56accc7SDimitry Andricdefm FCVT_WU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00001, XFINX, "fcvt.wu.s">, 3430eae32dcSDimitry Andric Sched<[WriteFCvtF32ToI32, ReadFCvtF32ToI32]>; 344d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_WU_S, "fcvt.wu.s", XFINX>; 3450b57cec5SDimitry Andric 3460eae32dcSDimitry Andriclet mayRaiseFPException = 0 in 3470eae32dcSDimitry Andricdef FMV_X_W : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR32, "fmv.x.w">, 3480eae32dcSDimitry Andric Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>; 3490eae32dcSDimitry Andric 3500eae32dcSDimitry Andriclet SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in { 351d56accc7SDimitry Andricdefm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", FINX>; 352d56accc7SDimitry Andricdefm FLT_S : FPCmp_rr_m<0b1010000, 0b001, "flt.s", FINX>; 353d56accc7SDimitry Andricdefm FLE_S : FPCmp_rr_m<0b1010000, 0b000, "fle.s", FINX>; 3540b57cec5SDimitry Andric} 3550b57cec5SDimitry Andric 3560eae32dcSDimitry Andriclet mayRaiseFPException = 0 in 357d56accc7SDimitry Andricdefm FCLASS_S : FPUnaryOp_r_m<0b1110000, 0b00000, 0b001, XFINX, "fclass.s">, 3580eae32dcSDimitry Andric Sched<[WriteFClass32, ReadFClass32]>; 3590b57cec5SDimitry Andric 360d56accc7SDimitry Andricdefm FCVT_S_W : FPUnaryOp_r_frm_m<0b1101000, 0b00000, FXINX, "fcvt.s.w">, 3610eae32dcSDimitry Andric Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; 362d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_S_W, "fcvt.s.w", FXINX>; 3630b57cec5SDimitry Andric 364d56accc7SDimitry Andricdefm FCVT_S_WU : FPUnaryOp_r_frm_m<0b1101000, 0b00001, FXINX, "fcvt.s.wu">, 3650eae32dcSDimitry Andric Sched<[WriteFCvtI32ToF32, ReadFCvtI32ToF32]>; 366d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_S_WU, "fcvt.s.wu", FXINX>; 3670b57cec5SDimitry Andric 3680eae32dcSDimitry Andriclet mayRaiseFPException = 0 in 3690eae32dcSDimitry Andricdef FMV_W_X : FPUnaryOp_r<0b1111000, 0b00000, 0b000, FPR32, GPR, "fmv.w.x">, 3700eae32dcSDimitry Andric Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>; 3710b57cec5SDimitry Andric 372d56accc7SDimitry Andricdefm FCVT_L_S : FPUnaryOp_r_frm_m<0b1100000, 0b00010, XFIN64X, "fcvt.l.s">, 3730eae32dcSDimitry Andric Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; 374d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_L_S, "fcvt.l.s", XFIN64X>; 3750b57cec5SDimitry Andric 376d56accc7SDimitry Andricdefm FCVT_LU_S : FPUnaryOp_r_frm_m<0b1100000, 0b00011, XFIN64X, "fcvt.lu.s">, 3770eae32dcSDimitry Andric Sched<[WriteFCvtF32ToI64, ReadFCvtF32ToI64]>; 378d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_LU_S, "fcvt.lu.s", XFIN64X>; 3790b57cec5SDimitry Andric 380d56accc7SDimitry Andricdefm FCVT_S_L : FPUnaryOp_r_frm_m<0b1101000, 0b00010, FXIN64X, "fcvt.s.l">, 3810eae32dcSDimitry Andric Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; 382d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_S_L, "fcvt.s.l", FXIN64X>; 3830b57cec5SDimitry Andric 384d56accc7SDimitry Andricdefm FCVT_S_LU : FPUnaryOp_r_frm_m<0b1101000, 0b00011, FXIN64X, "fcvt.s.lu">, 3850eae32dcSDimitry Andric Sched<[WriteFCvtI64ToF32, ReadFCvtI64ToF32]>; 386d56accc7SDimitry Andricdefm : FPUnaryOpDynFrmAlias_m<FCVT_S_LU, "fcvt.s.lu", FXIN64X>; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3890b57cec5SDimitry Andric// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) 3900b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andriclet Predicates = [HasStdExtF] in { 3930b57cec5SDimitry Andricdef : InstAlias<"flw $rd, (${rs1})", (FLW FPR32:$rd, GPR:$rs1, 0), 0>; 3940b57cec5SDimitry Andricdef : InstAlias<"fsw $rs2, (${rs1})", (FSW FPR32:$rs2, GPR:$rs1, 0), 0>; 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andricdef : InstAlias<"fmv.s $rd, $rs", (FSGNJ_S FPR32:$rd, FPR32:$rs, FPR32:$rs)>; 3970b57cec5SDimitry Andricdef : InstAlias<"fabs.s $rd, $rs", (FSGNJX_S FPR32:$rd, FPR32:$rs, FPR32:$rs)>; 3980b57cec5SDimitry Andricdef : InstAlias<"fneg.s $rd, $rs", (FSGNJN_S FPR32:$rd, FPR32:$rs, FPR32:$rs)>; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric// fgt.s/fge.s are recognised by the GNU assembler but the canonical 4010b57cec5SDimitry Andric// flt.s/fle.s forms will always be printed. Therefore, set a zero weight. 4020b57cec5SDimitry Andricdef : InstAlias<"fgt.s $rd, $rs, $rt", 4030b57cec5SDimitry Andric (FLT_S GPR:$rd, FPR32:$rt, FPR32:$rs), 0>; 4040b57cec5SDimitry Andricdef : InstAlias<"fge.s $rd, $rs, $rt", 4050b57cec5SDimitry Andric (FLE_S GPR:$rd, FPR32:$rt, FPR32:$rs), 0>; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric// The following csr instructions actually alias instructions from the base ISA. 4080b57cec5SDimitry Andric// However, it only makes sense to support them when the F extension is enabled. 4090b57cec5SDimitry Andric// NOTE: "frcsr", "frrm", and "frflags" are more specialized version of "csrr". 410fe6060f1SDimitry Andricdef : InstAlias<"frcsr $rd", (CSRRS GPR:$rd, SysRegFCSR.Encoding, X0), 2>; 411fe6060f1SDimitry Andricdef : InstAlias<"fscsr $rd, $rs", (CSRRW GPR:$rd, SysRegFCSR.Encoding, GPR:$rs)>; 412fe6060f1SDimitry Andricdef : InstAlias<"fscsr $rs", (CSRRW X0, SysRegFCSR.Encoding, GPR:$rs), 2>; 4130b57cec5SDimitry Andric 4148bcb0991SDimitry Andric// frsr, fssr are obsolete aliases replaced by frcsr, fscsr, so give them 4158bcb0991SDimitry Andric// zero weight. 416fe6060f1SDimitry Andricdef : InstAlias<"frsr $rd", (CSRRS GPR:$rd, SysRegFCSR.Encoding, X0), 0>; 417fe6060f1SDimitry Andricdef : InstAlias<"fssr $rd, $rs", (CSRRW GPR:$rd, SysRegFCSR.Encoding, GPR:$rs), 0>; 418fe6060f1SDimitry Andricdef : InstAlias<"fssr $rs", (CSRRW X0, SysRegFCSR.Encoding, GPR:$rs), 0>; 4198bcb0991SDimitry Andric 420fe6060f1SDimitry Andricdef : InstAlias<"frrm $rd", (CSRRS GPR:$rd, SysRegFRM.Encoding, X0), 2>; 421fe6060f1SDimitry Andricdef : InstAlias<"fsrm $rd, $rs", (CSRRW GPR:$rd, SysRegFRM.Encoding, GPR:$rs)>; 422fe6060f1SDimitry Andricdef : InstAlias<"fsrm $rs", (CSRRW X0, SysRegFRM.Encoding, GPR:$rs), 2>; 423fe6060f1SDimitry Andricdef : InstAlias<"fsrmi $rd, $imm", (CSRRWI GPR:$rd, SysRegFRM.Encoding, uimm5:$imm)>; 424fe6060f1SDimitry Andricdef : InstAlias<"fsrmi $imm", (CSRRWI X0, SysRegFRM.Encoding, uimm5:$imm), 2>; 4250b57cec5SDimitry Andric 426fe6060f1SDimitry Andricdef : InstAlias<"frflags $rd", (CSRRS GPR:$rd, SysRegFFLAGS.Encoding, X0), 2>; 427fe6060f1SDimitry Andricdef : InstAlias<"fsflags $rd, $rs", (CSRRW GPR:$rd, SysRegFFLAGS.Encoding, GPR:$rs)>; 428fe6060f1SDimitry Andricdef : InstAlias<"fsflags $rs", (CSRRW X0, SysRegFFLAGS.Encoding, GPR:$rs), 2>; 429fe6060f1SDimitry Andricdef : InstAlias<"fsflagsi $rd, $imm", (CSRRWI GPR:$rd, SysRegFFLAGS.Encoding, uimm5:$imm)>; 430fe6060f1SDimitry Andricdef : InstAlias<"fsflagsi $imm", (CSRRWI X0, SysRegFFLAGS.Encoding, uimm5:$imm), 2>; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric// fmv.w.x and fmv.x.w were previously known as fmv.s.x and fmv.x.s. Both 4330b57cec5SDimitry Andric// spellings should be supported by standard tools. 4340b57cec5SDimitry Andricdef : MnemonicAlias<"fmv.s.x", "fmv.w.x">; 4350b57cec5SDimitry Andricdef : MnemonicAlias<"fmv.x.s", "fmv.x.w">; 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andricdef PseudoFLW : PseudoFloatLoad<"flw", FPR32>; 4380b57cec5SDimitry Andricdef PseudoFSW : PseudoStore<"fsw", FPR32>; 43904eeddc0SDimitry Andriclet usesCustomInserter = 1 in { 44004eeddc0SDimitry Andricdef PseudoQuietFLE_S : PseudoQuietFCMP<FPR32>; 44104eeddc0SDimitry Andricdef PseudoQuietFLT_S : PseudoQuietFCMP<FPR32>; 44204eeddc0SDimitry Andric} 4430b57cec5SDimitry Andric} // Predicates = [HasStdExtF] 4440b57cec5SDimitry Andric 445d56accc7SDimitry Andriclet Predicates = [HasStdExtZfinx] in { 446d56accc7SDimitry Andricdef : InstAlias<"fabs.s $rd, $rs", (FSGNJX_S_INX FPR32INX:$rd, FPR32INX:$rs, FPR32INX:$rs)>; 447d56accc7SDimitry Andricdef : InstAlias<"fneg.s $rd, $rs", (FSGNJN_S_INX FPR32INX:$rd, FPR32INX:$rs, FPR32INX:$rs)>; 448d56accc7SDimitry Andric 449d56accc7SDimitry Andricdef : InstAlias<"fgt.s $rd, $rs, $rt", 450d56accc7SDimitry Andric (FLT_S_INX GPR:$rd, FPR32INX:$rt, FPR32INX:$rs), 0>; 451d56accc7SDimitry Andricdef : InstAlias<"fge.s $rd, $rs, $rt", 452d56accc7SDimitry Andric (FLE_S_INX GPR:$rd, FPR32INX:$rt, FPR32INX:$rs), 0>; 453d56accc7SDimitry Andric} // Predicates = [HasStdExtZfinx] 454d56accc7SDimitry Andric 4550b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 4560b57cec5SDimitry Andric// Pseudo-instructions and codegen patterns 4570b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 4580b57cec5SDimitry Andric 4595ffd83dbSDimitry Andric/// Floating point constants 4605ffd83dbSDimitry Andricdef fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>; 46104eeddc0SDimitry Andricdef fpimmneg0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(-0.0); }]>; 4625ffd83dbSDimitry Andric 4630b57cec5SDimitry Andric/// Generic pattern classes 46404eeddc0SDimitry Andricclass PatSetCC<RegisterClass Ty, SDPatternOperator OpNode, CondCode Cond, RVInst Inst> 46504eeddc0SDimitry Andric : Pat<(OpNode Ty:$rs1, Ty:$rs2, Cond), (Inst $rs1, $rs2)>; 46604eeddc0SDimitry Andric 4670b57cec5SDimitry Andricclass PatFpr32Fpr32<SDPatternOperator OpNode, RVInstR Inst> 4680b57cec5SDimitry Andric : Pat<(OpNode FPR32:$rs1, FPR32:$rs2), (Inst $rs1, $rs2)>; 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andricclass PatFpr32Fpr32DynFrm<SDPatternOperator OpNode, RVInstRFrm Inst> 4710b57cec5SDimitry Andric : Pat<(OpNode FPR32:$rs1, FPR32:$rs2), (Inst $rs1, $rs2, 0b111)>; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andriclet Predicates = [HasStdExtF] in { 4740b57cec5SDimitry Andric 4755ffd83dbSDimitry Andric/// Float constants 4765ffd83dbSDimitry Andricdef : Pat<(f32 (fpimm0)), (FMV_W_X X0)>; 47704eeddc0SDimitry Andricdef : Pat<(f32 (fpimmneg0)), (FSGNJN_S (FMV_W_X X0), (FMV_W_X X0))>; 4785ffd83dbSDimitry Andric 4790b57cec5SDimitry Andric/// Float conversion operations 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric// [u]int32<->float conversion patterns must be gated on IsRV32 or IsRV64, so 4820b57cec5SDimitry Andric// are defined later. 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric/// Float arithmetic operations 4850b57cec5SDimitry Andric 4860eae32dcSDimitry Andricdef : PatFpr32Fpr32DynFrm<any_fadd, FADD_S>; 4870eae32dcSDimitry Andricdef : PatFpr32Fpr32DynFrm<any_fsub, FSUB_S>; 4880eae32dcSDimitry Andricdef : PatFpr32Fpr32DynFrm<any_fmul, FMUL_S>; 4890eae32dcSDimitry Andricdef : PatFpr32Fpr32DynFrm<any_fdiv, FDIV_S>; 4900b57cec5SDimitry Andric 4910eae32dcSDimitry Andricdef : Pat<(any_fsqrt FPR32:$rs1), (FSQRT_S FPR32:$rs1, 0b111)>; 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andricdef : Pat<(fneg FPR32:$rs1), (FSGNJN_S $rs1, $rs1)>; 4940b57cec5SDimitry Andricdef : Pat<(fabs FPR32:$rs1), (FSGNJX_S $rs1, $rs1)>; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andricdef : PatFpr32Fpr32<fcopysign, FSGNJ_S>; 4970b57cec5SDimitry Andricdef : Pat<(fcopysign FPR32:$rs1, (fneg FPR32:$rs2)), (FSGNJN_S $rs1, $rs2)>; 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric// fmadd: rs1 * rs2 + rs3 5000eae32dcSDimitry Andricdef : Pat<(any_fma FPR32:$rs1, FPR32:$rs2, FPR32:$rs3), 5010b57cec5SDimitry Andric (FMADD_S $rs1, $rs2, $rs3, 0b111)>; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric// fmsub: rs1 * rs2 - rs3 5040eae32dcSDimitry Andricdef : Pat<(any_fma FPR32:$rs1, FPR32:$rs2, (fneg FPR32:$rs3)), 5050b57cec5SDimitry Andric (FMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric// fnmsub: -rs1 * rs2 + rs3 5080eae32dcSDimitry Andricdef : Pat<(any_fma (fneg FPR32:$rs1), FPR32:$rs2, FPR32:$rs3), 5090b57cec5SDimitry Andric (FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric// fnmadd: -rs1 * rs2 - rs3 5120eae32dcSDimitry Andricdef : Pat<(any_fma (fneg FPR32:$rs1), FPR32:$rs2, (fneg FPR32:$rs3)), 5130b57cec5SDimitry Andric (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; 5140b57cec5SDimitry Andric 515fe6060f1SDimitry Andric// The ratified 20191213 ISA spec defines fmin and fmax in a way that matches 516fe6060f1SDimitry Andric// LLVM's fminnum and fmaxnum 5170b57cec5SDimitry Andric// <https://github.com/riscv/riscv-isa-manual/commit/cd20cee7efd9bac7c5aa127ec3b451749d2b3cce>. 5180b57cec5SDimitry Andricdef : PatFpr32Fpr32<fminnum, FMIN_S>; 5190b57cec5SDimitry Andricdef : PatFpr32Fpr32<fmaxnum, FMAX_S>; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric/// Setcc 52204eeddc0SDimitry Andric// FIXME: SETEQ/SETLT/SETLE imply nonans, can we pick better instructions for 52304eeddc0SDimitry Andric// strict versions of those. 5240b57cec5SDimitry Andric 52504eeddc0SDimitry Andric// Match non-signaling FEQ_S 52604eeddc0SDimitry Andricdef : PatSetCC<FPR32, any_fsetcc, SETEQ, FEQ_S>; 52704eeddc0SDimitry Andricdef : PatSetCC<FPR32, any_fsetcc, SETOEQ, FEQ_S>; 52804eeddc0SDimitry Andricdef : PatSetCC<FPR32, strict_fsetcc, SETLT, PseudoQuietFLT_S>; 52904eeddc0SDimitry Andricdef : PatSetCC<FPR32, strict_fsetcc, SETOLT, PseudoQuietFLT_S>; 53004eeddc0SDimitry Andricdef : PatSetCC<FPR32, strict_fsetcc, SETLE, PseudoQuietFLE_S>; 53104eeddc0SDimitry Andricdef : PatSetCC<FPR32, strict_fsetcc, SETOLE, PseudoQuietFLE_S>; 53204eeddc0SDimitry Andric 53304eeddc0SDimitry Andric// Match signaling FEQ_S 53404eeddc0SDimitry Andricdef : Pat<(strict_fsetccs FPR32:$rs1, FPR32:$rs2, SETEQ), 53504eeddc0SDimitry Andric (AND (FLE_S $rs1, $rs2), 53604eeddc0SDimitry Andric (FLE_S $rs2, $rs1))>; 53704eeddc0SDimitry Andricdef : Pat<(strict_fsetccs FPR32:$rs1, FPR32:$rs2, SETOEQ), 53804eeddc0SDimitry Andric (AND (FLE_S $rs1, $rs2), 53904eeddc0SDimitry Andric (FLE_S $rs2, $rs1))>; 54004eeddc0SDimitry Andric// If both operands are the same, use a single FLE. 54104eeddc0SDimitry Andricdef : Pat<(strict_fsetccs FPR32:$rs1, FPR32:$rs1, SETEQ), 54204eeddc0SDimitry Andric (FLE_S $rs1, $rs1)>; 54304eeddc0SDimitry Andricdef : Pat<(strict_fsetccs FPR32:$rs1, FPR32:$rs1, SETOEQ), 54404eeddc0SDimitry Andric (FLE_S $rs1, $rs1)>; 54504eeddc0SDimitry Andric 54604eeddc0SDimitry Andricdef : PatSetCC<FPR32, any_fsetccs, SETLT, FLT_S>; 54704eeddc0SDimitry Andricdef : PatSetCC<FPR32, any_fsetccs, SETOLT, FLT_S>; 54804eeddc0SDimitry Andricdef : PatSetCC<FPR32, any_fsetccs, SETLE, FLE_S>; 54904eeddc0SDimitry Andricdef : PatSetCC<FPR32, any_fsetccs, SETOLE, FLE_S>; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andricdef Select_FPR32_Using_CC_GPR : SelectCC_rrirr<FPR32, GPR>; 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric/// Loads 5540b57cec5SDimitry Andric 555fe6060f1SDimitry Andricdefm : LdPat<load, FLW, f32>; 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric/// Stores 5580b57cec5SDimitry Andric 559fe6060f1SDimitry Andricdefm : StPat<store, FSW, FPR32, f32>; 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric} // Predicates = [HasStdExtF] 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andriclet Predicates = [HasStdExtF, IsRV32] in { 564e8d8bef9SDimitry Andric// Moves (no conversion) 565fe6060f1SDimitry Andricdef : Pat<(bitconvert (i32 GPR:$rs1)), (FMV_W_X GPR:$rs1)>; 566fe6060f1SDimitry Andricdef : Pat<(i32 (bitconvert FPR32:$rs1)), (FMV_X_W FPR32:$rs1)>; 567e8d8bef9SDimitry Andric 5680b57cec5SDimitry Andric// float->[u]int. Round-to-zero must be used. 5690eae32dcSDimitry Andricdef : Pat<(i32 (any_fp_to_sint FPR32:$rs1)), (FCVT_W_S $rs1, 0b001)>; 5700eae32dcSDimitry Andricdef : Pat<(i32 (any_fp_to_uint FPR32:$rs1)), (FCVT_WU_S $rs1, 0b001)>; 571fe6060f1SDimitry Andric 572349cc55cSDimitry Andric// Saturating float->[u]int32. 57304eeddc0SDimitry Andricdef : Pat<(i32 (riscv_fcvt_x FPR32:$rs1, timm:$frm)), (FCVT_W_S $rs1, timm:$frm)>; 57404eeddc0SDimitry Andricdef : Pat<(i32 (riscv_fcvt_xu FPR32:$rs1, timm:$frm)), (FCVT_WU_S $rs1, timm:$frm)>; 575349cc55cSDimitry Andric 576fe6060f1SDimitry Andric// float->int32 with current rounding mode. 57704eeddc0SDimitry Andricdef : Pat<(i32 (any_lrint FPR32:$rs1)), (FCVT_W_S $rs1, 0b111)>; 578fe6060f1SDimitry Andric 579fe6060f1SDimitry Andric// float->int32 rounded to nearest with ties rounded away from zero. 58004eeddc0SDimitry Andricdef : Pat<(i32 (any_lround FPR32:$rs1)), (FCVT_W_S $rs1, 0b100)>; 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric// [u]int->float. Match GCC and default to using dynamic rounding mode. 5830eae32dcSDimitry Andricdef : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_S_W $rs1, 0b111)>; 5840eae32dcSDimitry Andricdef : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_S_WU $rs1, 0b111)>; 5850b57cec5SDimitry Andric} // Predicates = [HasStdExtF, IsRV32] 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andriclet Predicates = [HasStdExtF, IsRV64] in { 588e8d8bef9SDimitry Andric// Moves (no conversion) 5890b57cec5SDimitry Andricdef : Pat<(riscv_fmv_w_x_rv64 GPR:$src), (FMV_W_X GPR:$src)>; 5900b57cec5SDimitry Andricdef : Pat<(riscv_fmv_x_anyextw_rv64 FPR32:$src), (FMV_X_W FPR32:$src)>; 591e8d8bef9SDimitry Andricdef : Pat<(sext_inreg (riscv_fmv_x_anyextw_rv64 FPR32:$src), i32), 5920b57cec5SDimitry Andric (FMV_X_W FPR32:$src)>; 5930b57cec5SDimitry Andric 594fe6060f1SDimitry Andric// Use target specific isd nodes to help us remember the result is sign 595fe6060f1SDimitry Andric// extended. Matching sext_inreg+fptoui/fptosi may cause the conversion to be 596fe6060f1SDimitry Andric// duplicated if it has another user that didn't need the sign_extend. 59704eeddc0SDimitry Andricdef : Pat<(riscv_any_fcvt_w_rv64 FPR32:$rs1, timm:$frm), (FCVT_W_S $rs1, timm:$frm)>; 59804eeddc0SDimitry Andricdef : Pat<(riscv_any_fcvt_wu_rv64 FPR32:$rs1, timm:$frm), (FCVT_WU_S $rs1, timm:$frm)>; 5990b57cec5SDimitry Andric 600fe6060f1SDimitry Andric// float->[u]int64. Round-to-zero must be used. 6010eae32dcSDimitry Andricdef : Pat<(i64 (any_fp_to_sint FPR32:$rs1)), (FCVT_L_S $rs1, 0b001)>; 6020eae32dcSDimitry Andricdef : Pat<(i64 (any_fp_to_uint FPR32:$rs1)), (FCVT_LU_S $rs1, 0b001)>; 603fe6060f1SDimitry Andric 604349cc55cSDimitry Andric// Saturating float->[u]int64. 60504eeddc0SDimitry Andricdef : Pat<(i64 (riscv_fcvt_x FPR32:$rs1, timm:$frm)), (FCVT_L_S $rs1, timm:$frm)>; 60604eeddc0SDimitry Andricdef : Pat<(i64 (riscv_fcvt_xu FPR32:$rs1, timm:$frm)), (FCVT_LU_S $rs1, timm:$frm)>; 607349cc55cSDimitry Andric 608fe6060f1SDimitry Andric// float->int64 with current rounding mode. 60904eeddc0SDimitry Andricdef : Pat<(i64 (any_lrint FPR32:$rs1)), (FCVT_L_S $rs1, 0b111)>; 61004eeddc0SDimitry Andricdef : Pat<(i64 (any_llrint FPR32:$rs1)), (FCVT_L_S $rs1, 0b111)>; 611fe6060f1SDimitry Andric 612fe6060f1SDimitry Andric// float->int64 rounded to neartest with ties rounded away from zero. 61304eeddc0SDimitry Andricdef : Pat<(i64 (any_lround FPR32:$rs1)), (FCVT_L_S $rs1, 0b100)>; 61404eeddc0SDimitry Andricdef : Pat<(i64 (any_llround FPR32:$rs1)), (FCVT_L_S $rs1, 0b100)>; 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric// [u]int->fp. Match GCC and default to using dynamic rounding mode. 6170eae32dcSDimitry Andricdef : Pat<(any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_S_W $rs1, 0b111)>; 6180eae32dcSDimitry Andricdef : Pat<(any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1)))), (FCVT_S_WU $rs1, 0b111)>; 6190eae32dcSDimitry Andricdef : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_S_L $rs1, 0b111)>; 6200eae32dcSDimitry Andricdef : Pat<(any_uint_to_fp (i64 GPR:$rs1)), (FCVT_S_LU $rs1, 0b111)>; 6210b57cec5SDimitry Andric} // Predicates = [HasStdExtF, IsRV64] 622