1//=-- LoongArchInstrInfoF.td - Single-Precision Float instr --*- 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 baisc single-precision floating-point instructions. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// LoongArch specific DAG Nodes. 15//===----------------------------------------------------------------------===// 16 17def SDT_LoongArchMOVGR2FR_W_LA64 18 : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i64>]>; 19def SDT_LoongArchMOVFR2GR_S_LA64 20 : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, f32>]>; 21def SDT_LoongArchFTINT : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; 22 23def loongarch_movgr2fr_w_la64 24 : SDNode<"LoongArchISD::MOVGR2FR_W_LA64", SDT_LoongArchMOVGR2FR_W_LA64>; 25def loongarch_movfr2gr_s_la64 26 : SDNode<"LoongArchISD::MOVFR2GR_S_LA64", SDT_LoongArchMOVFR2GR_S_LA64>; 27def loongarch_ftint : SDNode<"LoongArchISD::FTINT", SDT_LoongArchFTINT>; 28 29//===----------------------------------------------------------------------===// 30// Instructions 31//===----------------------------------------------------------------------===// 32 33let Predicates = [HasBasicF] in { 34 35// Arithmetic Operation Instructions 36def FADD_S : FP_ALU_3R<0b00000001000000001, "fadd.s", FPR32>; 37def FSUB_S : FP_ALU_3R<0b00000001000000101, "fsub.s", FPR32>; 38def FMUL_S : FP_ALU_3R<0b00000001000001001, "fmul.s", FPR32>; 39def FDIV_S : FP_ALU_3R<0b00000001000001101, "fdiv.s", FPR32>; 40def FMADD_S : FP_ALU_4R<0b000010000001, "fmadd.s", FPR32>; 41def FMSUB_S : FP_ALU_4R<0b000010000101, "fmsub.s", FPR32>; 42def FNMADD_S : FP_ALU_4R<0b000010001001, "fnmadd.s", FPR32>; 43def FNMSUB_S : FP_ALU_4R<0b000010001101, "fnmsub.s", FPR32>; 44def FMAX_S : FP_ALU_3R<0b00000001000010001, "fmax.s", FPR32>; 45def FMIN_S : FP_ALU_3R<0b00000001000010101, "fmin.s", FPR32>; 46def FMAXA_S : FP_ALU_3R<0b00000001000011001, "fmaxa.s", FPR32>; 47def FMINA_S : FP_ALU_3R<0b00000001000011101, "fmina.s", FPR32>; 48def FABS_S : FP_ALU_2R<0b0000000100010100000001, "fabs.s", FPR32>; 49def FNEG_S : FP_ALU_2R<0b0000000100010100000101, "fneg.s", FPR32>; 50def FSQRT_S : FP_ALU_2R<0b0000000100010100010001, "fsqrt.s", FPR32>; 51def FRECIP_S : FP_ALU_2R<0b0000000100010100010101, "frecip.s", FPR32>; 52def FRSQRT_S : FP_ALU_2R<0b0000000100010100011001, "frsqrt.s", FPR32>; 53def FSCALEB_S : FP_ALU_3R<0b00000001000100001, "fscaleb.s", FPR32>; 54def FLOGB_S : FP_ALU_2R<0b0000000100010100001001, "flogb.s", FPR32>; 55def FCOPYSIGN_S : FP_ALU_3R<0b00000001000100101, "fcopysign.s", FPR32>; 56def FCLASS_S : FP_ALU_2R<0b0000000100010100001101, "fclass.s", FPR32>; 57 58 59// Comparison Instructions 60def FCMP_CAF_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CAF, "fcmp.caf.s", FPR32>; 61def FCMP_CUN_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CUN, "fcmp.cun.s", FPR32>; 62def FCMP_CEQ_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CEQ, "fcmp.ceq.s", FPR32>; 63def FCMP_CUEQ_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CUEQ, "fcmp.cueq.s", FPR32>; 64def FCMP_CLT_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CLT, "fcmp.clt.s", FPR32>; 65def FCMP_CULT_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CULT, "fcmp.cult.s", FPR32>; 66def FCMP_CLE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CLE, "fcmp.cle.s", FPR32>; 67def FCMP_CULE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CULE, "fcmp.cule.s", FPR32>; 68def FCMP_CNE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CNE, "fcmp.cne.s", FPR32>; 69def FCMP_COR_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_COR, "fcmp.cor.s", FPR32>; 70def FCMP_CUNE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_CUNE, "fcmp.cune.s", FPR32>; 71def FCMP_SAF_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SAF, "fcmp.saf.s", FPR32>; 72def FCMP_SUN_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SUN, "fcmp.sun.s", FPR32>; 73def FCMP_SEQ_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SEQ, "fcmp.seq.s", FPR32>; 74def FCMP_SUEQ_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SUEQ, "fcmp.sueq.s", FPR32>; 75def FCMP_SLT_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SLT, "fcmp.slt.s", FPR32>; 76def FCMP_SULT_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SULT, "fcmp.sult.s", FPR32>; 77def FCMP_SLE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SLE, "fcmp.sle.s", FPR32>; 78def FCMP_SULE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SULE, "fcmp.sule.s", FPR32>; 79def FCMP_SNE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SNE, "fcmp.sne.s", FPR32>; 80def FCMP_SOR_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SOR, "fcmp.sor.s", FPR32>; 81def FCMP_SUNE_S : FP_CMP<FPCMP_OPC_S, FPCMP_COND_SUNE, "fcmp.sune.s", FPR32>; 82 83// Conversion Instructions 84def FFINT_S_W : FP_CONV<0b0000000100011101000100, "ffint.s.w", FPR32, FPR32>; 85def FTINT_W_S : FP_CONV<0b0000000100011011000001, "ftint.w.s", FPR32, FPR32>; 86def FTINTRM_W_S : FP_CONV<0b0000000100011010000001, "ftintrm.w.s", FPR32, 87 FPR32>; 88def FTINTRP_W_S : FP_CONV<0b0000000100011010010001, "ftintrp.w.s", FPR32, 89 FPR32>; 90def FTINTRZ_W_S : FP_CONV<0b0000000100011010100001, "ftintrz.w.s", FPR32, 91 FPR32>; 92def FTINTRNE_W_S : FP_CONV<0b0000000100011010110001, "ftintrne.w.s", FPR32, 93 FPR32>; 94def FRINT_S : FP_CONV<0b0000000100011110010001, "frint.s", FPR32, FPR32>; 95 96// Move Instructions 97def FSEL_S : FP_SEL<0b00001101000000, "fsel", FPR32>; 98def FMOV_S : FP_MOV<0b0000000100010100100101, "fmov.s", FPR32, FPR32>; 99def MOVGR2FR_W : FP_MOV<0b0000000100010100101001, "movgr2fr.w", FPR32, GPR>; 100def MOVFR2GR_S : FP_MOV<0b0000000100010100101101, "movfr2gr.s", GPR, FPR32>; 101def MOVGR2FCSR : FP_MOV<0b0000000100010100110000, "movgr2fcsr", FCSR, GPR>; 102def MOVFCSR2GR : FP_MOV<0b0000000100010100110010, "movfcsr2gr", GPR, FCSR>; 103def MOVFR2CF_S : FP_MOV<0b0000000100010100110100, "movfr2cf", CFR, FPR32>; 104def MOVCF2FR_S : FP_MOV<0b0000000100010100110101, "movcf2fr", FPR32, CFR>; 105def MOVGR2CF : FP_MOV<0b0000000100010100110110, "movgr2cf", CFR, GPR>; 106def MOVCF2GR : FP_MOV<0b0000000100010100110111, "movcf2gr", GPR, CFR>; 107 108// Branch Instructions 109def BCEQZ : FP_BRANCH<0b01001000, "bceqz">; 110def BCNEZ : FP_BRANCH<0b01001001, "bcnez">; 111 112// Common Memory Access Instructions 113def FLD_S : FP_LOAD_2RI12<0b0010101100, "fld.s", FPR32>; 114def FST_S : FP_STORE_2RI12<0b0010101101, "fst.s", FPR32>; 115def FLDX_S : FP_LOAD_3R<0b00111000001100000, "fldx.s", FPR32>; 116def FSTX_S : FP_STORE_3R<0b00111000001110000, "fstx.s", FPR32>; 117 118// Bound Check Memory Access Instructions 119def FLDGT_S : FP_LOAD_3R<0b00111000011101000, "fldgt.s", FPR32>; 120def FLDLE_S : FP_LOAD_3R<0b00111000011101010, "fldle.s", FPR32>; 121def FSTGT_S : FP_STORE_3R<0b00111000011101100, "fstgt.s", FPR32>; 122def FSTLE_S : FP_STORE_3R<0b00111000011101110, "fstle.s", FPR32>; 123 124// Pseudo instructions for spill/reload CFRs. 125let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 126def PseudoST_CFR : Pseudo<(outs), 127 (ins CFR:$ccd, GPR:$rj, grlenimm:$imm)>; 128let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 129def PseudoLD_CFR : Pseudo<(outs CFR:$ccd), 130 (ins GPR:$rj, grlenimm:$imm)>; 131} // Predicates = [HasBasicF] 132 133//===----------------------------------------------------------------------===// 134// Pseudo-instructions and codegen patterns 135//===----------------------------------------------------------------------===// 136 137/// Generic pattern classes 138 139class PatFpr<SDPatternOperator OpNode, LAInst Inst, RegisterClass RegTy> 140 : Pat<(OpNode RegTy:$fj), (Inst $fj)>; 141class PatFprFpr<SDPatternOperator OpNode, LAInst Inst, RegisterClass RegTy> 142 : Pat<(OpNode RegTy:$fj, RegTy:$fk), (Inst $fj, $fk)>; 143 144let Predicates = [HasBasicF] in { 145 146/// Float arithmetic operations 147 148def : PatFprFpr<fadd, FADD_S, FPR32>; 149def : PatFprFpr<fsub, FSUB_S, FPR32>; 150def : PatFprFpr<fmul, FMUL_S, FPR32>; 151def : PatFprFpr<fdiv, FDIV_S, FPR32>; 152def : PatFprFpr<fcopysign, FCOPYSIGN_S, FPR32>; 153def : PatFprFpr<fmaxnum_ieee, FMAX_S, FPR32>; 154def : PatFprFpr<fminnum_ieee, FMIN_S, FPR32>; 155def : PatFpr<fneg, FNEG_S, FPR32>; 156def : PatFpr<fabs, FABS_S, FPR32>; 157def : PatFpr<fsqrt, FSQRT_S, FPR32>; 158 159def : Pat<(fdiv fpimm1, (fsqrt FPR32:$fj)), (FRSQRT_S FPR32:$fj)>; 160 161def : Pat<(fcanonicalize FPR32:$fj), (FMAX_S $fj, $fj)>; 162 163/// Setcc 164 165// Match non-signaling comparison 166 167class PatFPSetcc<CondCode cc, LAInst CmpInst, RegisterClass RegTy> 168 : Pat<(any_fsetcc RegTy:$fj, RegTy:$fk, cc), 169 (CmpInst RegTy:$fj, RegTy:$fk)>; 170// SETOGT/SETOGE/SETUGT/SETUGE/SETGE/SETNE/SETGT will expand into 171// SETOLT/SETOLE/SETULT/SETULE/SETLE/SETEQ/SETLT. 172def : PatFPSetcc<SETOEQ, FCMP_CEQ_S, FPR32>; 173def : PatFPSetcc<SETEQ, FCMP_CEQ_S, FPR32>; 174def : PatFPSetcc<SETOLT, FCMP_CLT_S, FPR32>; 175def : PatFPSetcc<SETOLE, FCMP_CLE_S, FPR32>; 176def : PatFPSetcc<SETLE, FCMP_CLE_S, FPR32>; 177def : PatFPSetcc<SETONE, FCMP_CNE_S, FPR32>; 178def : PatFPSetcc<SETO, FCMP_COR_S, FPR32>; 179def : PatFPSetcc<SETUEQ, FCMP_CUEQ_S, FPR32>; 180def : PatFPSetcc<SETULT, FCMP_CULT_S, FPR32>; 181def : PatFPSetcc<SETULE, FCMP_CULE_S, FPR32>; 182def : PatFPSetcc<SETUNE, FCMP_CUNE_S, FPR32>; 183def : PatFPSetcc<SETUO, FCMP_CUN_S, FPR32>; 184def : PatFPSetcc<SETLT, FCMP_CLT_S, FPR32>; 185 186multiclass PatFPBrcond<CondCode cc, LAInst CmpInst, RegisterClass RegTy> { 187 def : Pat<(brcond (xor (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), -1), 188 bb:$imm21), 189 (BCEQZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>; 190 def : Pat<(brcond (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), bb:$imm21), 191 (BCNEZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>; 192} 193 194defm : PatFPBrcond<SETOEQ, FCMP_CEQ_S, FPR32>; 195defm : PatFPBrcond<SETOLT, FCMP_CLT_S, FPR32>; 196defm : PatFPBrcond<SETOLE, FCMP_CLE_S, FPR32>; 197defm : PatFPBrcond<SETONE, FCMP_CNE_S, FPR32>; 198defm : PatFPBrcond<SETO, FCMP_COR_S, FPR32>; 199defm : PatFPBrcond<SETUEQ, FCMP_CUEQ_S, FPR32>; 200defm : PatFPBrcond<SETULT, FCMP_CULT_S, FPR32>; 201defm : PatFPBrcond<SETULE, FCMP_CULE_S, FPR32>; 202defm : PatFPBrcond<SETUNE, FCMP_CUNE_S, FPR32>; 203defm : PatFPBrcond<SETUO, FCMP_CUN_S, FPR32>; 204defm : PatFPBrcond<SETLT, FCMP_CLT_S, FPR32>; 205 206// Match signaling comparison 207 208class PatStrictFsetccs<CondCode cc, LAInst CmpInst, RegisterClass RegTy> 209 : Pat<(strict_fsetccs RegTy:$fj, RegTy:$fk, cc), 210 (CmpInst RegTy:$fj, RegTy:$fk)>; 211def : PatStrictFsetccs<SETOEQ, FCMP_SEQ_S, FPR32>; 212def : PatStrictFsetccs<SETOLT, FCMP_SLT_S, FPR32>; 213def : PatStrictFsetccs<SETOLE, FCMP_SLE_S, FPR32>; 214def : PatStrictFsetccs<SETONE, FCMP_SNE_S, FPR32>; 215def : PatStrictFsetccs<SETO, FCMP_SOR_S, FPR32>; 216def : PatStrictFsetccs<SETUEQ, FCMP_SUEQ_S, FPR32>; 217def : PatStrictFsetccs<SETULT, FCMP_SULT_S, FPR32>; 218def : PatStrictFsetccs<SETULE, FCMP_SULE_S, FPR32>; 219def : PatStrictFsetccs<SETUNE, FCMP_SUNE_S, FPR32>; 220def : PatStrictFsetccs<SETUO, FCMP_SUN_S, FPR32>; 221def : PatStrictFsetccs<SETLT, FCMP_SLT_S, FPR32>; 222 223/// Select 224 225def : Pat<(select CFR:$cc, FPR32:$fk, FPR32:$fj), 226 (FSEL_S FPR32:$fj, FPR32:$fk, CFR:$cc)>; 227 228/// Selectcc 229 230class PatFPSelectcc<CondCode cc, LAInst CmpInst, LAInst SelInst, 231 RegisterClass RegTy> 232 : Pat<(select (GRLenVT (setcc RegTy:$a, RegTy:$b, cc)), RegTy:$t, RegTy:$f), 233 (SelInst RegTy:$f, RegTy:$t, (CmpInst RegTy:$a, RegTy:$b))>; 234def : PatFPSelectcc<SETOEQ, FCMP_CEQ_S, FSEL_S, FPR32>; 235def : PatFPSelectcc<SETOLT, FCMP_CLT_S, FSEL_S, FPR32>; 236def : PatFPSelectcc<SETOLE, FCMP_CLE_S, FSEL_S, FPR32>; 237def : PatFPSelectcc<SETONE, FCMP_CNE_S, FSEL_S, FPR32>; 238def : PatFPSelectcc<SETO, FCMP_COR_S, FSEL_S, FPR32>; 239def : PatFPSelectcc<SETUEQ, FCMP_CUEQ_S, FSEL_S, FPR32>; 240def : PatFPSelectcc<SETULT, FCMP_CULT_S, FSEL_S, FPR32>; 241def : PatFPSelectcc<SETULE, FCMP_CULE_S, FSEL_S, FPR32>; 242def : PatFPSelectcc<SETUNE, FCMP_CUNE_S, FSEL_S, FPR32>; 243def : PatFPSelectcc<SETUO, FCMP_CUN_S, FSEL_S, FPR32>; 244 245/// Loads 246 247defm : LdPat<load, FLD_S, f32>; 248def : RegRegLdPat<load, FLDX_S, f32>; 249 250/// Stores 251 252defm : StPat<store, FST_S, FPR32, f32>; 253def : RegRegStPat<store, FSTX_S, FPR32, f32>; 254 255/// Floating point constants 256 257def : Pat<(f32 fpimm0), (MOVGR2FR_W R0)>; 258def : Pat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W R0))>; 259def : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>; 260 261// FP Conversion 262def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_W_S FPR32:$src)>; 263 264// FP reciprocal operation 265def : Pat<(fdiv fpimm1, FPR32:$src), (FRECIP_S $src)>; 266 267// fmadd.s: fj * fk + fa 268def : Pat<(fma FPR32:$fj, FPR32:$fk, FPR32:$fa), (FMADD_S $fj, $fk, $fa)>; 269 270// fmsub.s: fj * fk - fa 271def : Pat<(fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa)), 272 (FMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; 273 274// fnmadd.s: -(fj * fk + fa) 275def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, FPR32:$fa)), 276 (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; 277 278// fnmadd.s: -fj * fk - fa (the nsz flag on the FMA) 279def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, (fneg FPR32:$fa)), 280 (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; 281 282// fnmsub.s: -fj * fk + fa 283def : Pat<(fma (fneg FPR32:$fj), FPR32:$fk, FPR32:$fa), 284 (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; 285} // Predicates = [HasBasicF] 286 287let Predicates = [HasBasicF, IsLA64] in { 288// GPR -> FPR 289def : Pat<(loongarch_movgr2fr_w_la64 GPR:$src), (MOVGR2FR_W GPR:$src)>; 290// FPR -> GPR 291def : Pat<(loongarch_movfr2gr_s_la64 FPR32:$src), 292 (MOVFR2GR_S FPR32:$src)>; 293// int -> f32 294def : Pat<(f32 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))), 295 (FFINT_S_W (MOVGR2FR_W GPR:$src))>; 296// uint -> f32 297def : Pat<(f32 (uint_to_fp (i64 (sexti32 (i64 GPR:$src))))), 298 (FFINT_S_W (MOVGR2FR_W GPR:$src))>; 299} // Predicates = [HasBasicF, IsLA64] 300 301// FP Rounding 302let Predicates = [HasBasicF, IsLA64] in { 303def : PatFpr<frint, FRINT_S, FPR32>; 304} // Predicates = [HasBasicF, IsLA64] 305 306let Predicates = [HasBasicF, IsLA32] in { 307// GPR -> FPR 308def : Pat<(bitconvert (i32 GPR:$src)), (MOVGR2FR_W GPR:$src)>; 309// FPR -> GPR 310def : Pat<(i32 (bitconvert FPR32:$src)), (MOVFR2GR_S FPR32:$src)>; 311// int -> f32 312def : Pat<(f32 (sint_to_fp (i32 GPR:$src))), (FFINT_S_W (MOVGR2FR_W GPR:$src))>; 313} // Predicates = [HasBasicF, IsLA32] 314