brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.6 KiB · e6cad1b Raw
370 lines · plain
1// LoongArchFloat64InstrInfo.td - Double-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-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the basic double-precision floating-point instructions.10//11//===----------------------------------------------------------------------===//12 13//===----------------------------------------------------------------------===//14// LoongArch specific DAG Nodes.15//===----------------------------------------------------------------------===//16 17def SDT_LoongArchMOVGR2FR_D18    : SDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisVT<1, i64>]>;19def SDT_LoongArchMOVGR2FR_D_LO_HI20    : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,21                           SDTCisSameAs<1, 2>]>;22 23// FPR<->GPR transfer operations24def loongarch_movgr2fr_d25    : SDNode<"LoongArchISD::MOVGR2FR_D", SDT_LoongArchMOVGR2FR_D>;26def loongarch_movgr2fr_d_lo_hi27    : SDNode<"LoongArchISD::MOVGR2FR_D_LO_HI", SDT_LoongArchMOVGR2FR_D_LO_HI>;28 29//===----------------------------------------------------------------------===//30// Instructions31//===----------------------------------------------------------------------===//32 33let Predicates = [HasBasicD] in {34 35// Arithmetic Operation Instructions36def FADD_D : FP_ALU_3R<0x01010000, FPR64>;37def FSUB_D : FP_ALU_3R<0x01030000, FPR64>;38def FMUL_D : FP_ALU_3R<0x01050000, FPR64>;39def FDIV_D : FP_ALU_3R<0x01070000, FPR64>;40def FMADD_D  : FP_ALU_4R<0x08200000, FPR64>;41def FMSUB_D  : FP_ALU_4R<0x08600000, FPR64>;42def FNMADD_D : FP_ALU_4R<0x08a00000, FPR64>;43def FNMSUB_D : FP_ALU_4R<0x08e00000, FPR64>;44def FMAX_D  : FP_ALU_3R<0x01090000, FPR64>;45def FMIN_D  : FP_ALU_3R<0x010b0000, FPR64>;46def FMAXA_D : FP_ALU_3R<0x010d0000, FPR64>;47def FMINA_D : FP_ALU_3R<0x010f0000, FPR64>;48def FABS_D   : FP_ALU_2R<0x01140800, FPR64>;49def FNEG_D   : FP_ALU_2R<0x01141800, FPR64>;50def FSQRT_D  : FP_ALU_2R<0x01144800, FPR64>;51def FRECIP_D : FP_ALU_2R<0x01145800, FPR64>;52def FRSQRT_D : FP_ALU_2R<0x01146800, FPR64>;53def FRECIPE_D : FP_ALU_2R<0x01147800, FPR64>;54def FRSQRTE_D : FP_ALU_2R<0x01148800, FPR64>;55def FSCALEB_D : FP_ALU_3R<0x01110000, FPR64>;56def FLOGB_D   : FP_ALU_2R<0x01142800, FPR64>;57def FCOPYSIGN_D : FP_ALU_3R<0x01130000, FPR64>;58def FCLASS_D  : FP_ALU_2R<0x01143800, FPR64>;59 60// Comparison Instructions61def FCMP_CAF_D  : FP_CMP<0x0c200000, FPR64>;62def FCMP_CUN_D  : FP_CMP<0x0c240000, FPR64>;63def FCMP_CEQ_D  : FP_CMP<0x0c220000, FPR64>;64def FCMP_CUEQ_D : FP_CMP<0x0c260000, FPR64>;65def FCMP_CLT_D  : FP_CMP<0x0c210000, FPR64>;66def FCMP_CULT_D : FP_CMP<0x0c250000, FPR64>;67def FCMP_CLE_D  : FP_CMP<0x0c230000, FPR64>;68def FCMP_CULE_D : FP_CMP<0x0c270000, FPR64>;69def FCMP_CNE_D  : FP_CMP<0x0c280000, FPR64>;70def FCMP_COR_D  : FP_CMP<0x0c2a0000, FPR64>;71def FCMP_CUNE_D : FP_CMP<0x0c2c0000, FPR64>;72def FCMP_SAF_D  : FP_CMP<0x0c208000, FPR64>;73def FCMP_SUN_D  : FP_CMP<0x0c248000, FPR64>;74def FCMP_SEQ_D  : FP_CMP<0x0c228000, FPR64>;75def FCMP_SUEQ_D : FP_CMP<0x0c268000, FPR64>;76def FCMP_SLT_D  : FP_CMP<0x0c218000, FPR64>;77def FCMP_SULT_D : FP_CMP<0x0c258000, FPR64>;78def FCMP_SLE_D  : FP_CMP<0x0c238000, FPR64>;79def FCMP_SULE_D : FP_CMP<0x0c278000, FPR64>;80def FCMP_SNE_D  : FP_CMP<0x0c288000, FPR64>;81def FCMP_SOR_D  : FP_CMP<0x0c2a8000, FPR64>;82def FCMP_SUNE_D : FP_CMP<0x0c2c8000, FPR64>;83 84// Conversion Instructions85def FFINT_S_L : FP_CONV<0x011d1800, FPR32, FPR64>;86def FTINT_L_S : FP_CONV<0x011b2400, FPR64, FPR32>;87def FTINTRM_L_S : FP_CONV<0x011a2400, FPR64, FPR32>;88def FTINTRP_L_S : FP_CONV<0x011a6400, FPR64, FPR32>;89def FTINTRZ_L_S : FP_CONV<0x011aa400, FPR64, FPR32>;90def FTINTRNE_L_S : FP_CONV<0x011ae400, FPR64, FPR32>;91def FCVT_S_D : FP_CONV<0x01191800, FPR32, FPR64>;92def FCVT_D_S : FP_CONV<0x01192400, FPR64, FPR32>;93def FFINT_D_W : FP_CONV<0x011d2000, FPR64, FPR32>;94def FFINT_D_L : FP_CONV<0x011d2800, FPR64, FPR64>;95def FTINT_W_D : FP_CONV<0x011b0800, FPR32, FPR64>;96def FTINT_L_D : FP_CONV<0x011b2800, FPR64, FPR64>;97def FTINTRM_W_D : FP_CONV<0x011a0800, FPR32, FPR64>;98def FTINTRM_L_D : FP_CONV<0x011a2800, FPR64, FPR64>;99def FTINTRP_W_D : FP_CONV<0x011a4800, FPR32, FPR64>;100def FTINTRP_L_D : FP_CONV<0x011a6800, FPR64, FPR64>;101def FTINTRZ_W_D : FP_CONV<0x011a8800, FPR32, FPR64>;102def FTINTRZ_L_D : FP_CONV<0x011aa800, FPR64, FPR64>;103def FTINTRNE_W_D : FP_CONV<0x011ac800, FPR32, FPR64>;104def FTINTRNE_L_D : FP_CONV<0x011ae800, FPR64, FPR64>;105def FRINT_D : FP_CONV<0x011e4800, FPR64, FPR64>;106 107// Move Instructions108def FMOV_D        : FP_MOV<0x01149800, FPR64, FPR64>;109def MOVFRH2GR_S   : FP_MOV<0x0114bc00, GPR, FPR64>;110let isCodeGenOnly = 1 in {111def MOVFR2GR_S_64 : FP_MOV<0x0114b400, GPR, FPR64>;112def FSEL_xD : FP_SEL<0x0d000000, FPR64>;113} // isCodeGenOnly = 1114let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$dst = $out" in {115def MOVGR2FRH_W : FPFmtMOV<0x0114ac00, (outs FPR64:$out),116                           (ins FPR64:$dst, GPR:$src),117                           "$dst, $src">;118} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$dst = $out"119 120// Common Memory Access Instructions121def FLD_D : FP_LOAD_2RI12<0x2b800000, FPR64>;122def FST_D : FP_STORE_2RI12<0x2bc00000, FPR64>;123def FLDX_D : FP_LOAD_3R<0x38340000, FPR64>;124def FSTX_D : FP_STORE_3R<0x383c0000, FPR64>;125 126// Bound Check Memory Access Instructions127def FLDGT_D : FP_LOAD_3R<0x38748000, FPR64>;128def FLDLE_D : FP_LOAD_3R<0x38758000, FPR64>;129def FSTGT_D : FP_STORE_3R<0x38768000, FPR64>;130def FSTLE_D : FP_STORE_3R<0x38778000, FPR64>;131 132} // Predicates = [HasBasicD]133 134// Instructions only available on LA64135let Predicates = [HasBasicD, IsLA64] in {136def MOVGR2FR_D  : FP_MOV<0x0114a800, FPR64, GPR>;137def MOVFR2GR_D  : FP_MOV<0x0114b800, GPR, FPR64>;138} // Predicates = [HasBasicD, IsLA64]139 140// Instructions only available on LA32141let Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1 in {142def MOVGR2FR_W_64 : FP_MOV<0x0114a400, FPR64, GPR>;143} // Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1144 145//===----------------------------------------------------------------------===//146// Pseudo-instructions and codegen patterns147//===----------------------------------------------------------------------===//148 149let Predicates = [HasBasicD] in {150 151/// Float arithmetic operations152 153def : PatFprFpr<fadd, FADD_D, FPR64>;154def : PatFprFpr<fsub, FSUB_D, FPR64>;155def : PatFprFpr<fmul, FMUL_D, FPR64>;156def : PatFprFpr<fdiv, FDIV_D, FPR64>;157def : PatFprFpr<fcopysign, FCOPYSIGN_D, FPR64>;158def : PatFprFpr<fmaxnum_ieee, FMAX_D, FPR64>;159def : PatFprFpr<fmaxnum, FMAX_D, FPR64>;160def : PatFprFpr<fminnum_ieee, FMIN_D, FPR64>;161def : PatFprFpr<fminnum, FMIN_D, FPR64>;162def : PatFpr<fneg, FNEG_D, FPR64>;163def : PatFpr<fabs, FABS_D, FPR64>;164def : PatFpr<fsqrt, FSQRT_D, FPR64>;165def : Pat<(fdiv fpimm1, (fsqrt FPR64:$fj)), (FRSQRT_D FPR64:$fj)>;166let Predicates = [IsLA32] in {167def : Pat<(fdiv (loongarch_movgr2fr_d_lo_hi (i32 0), (i32 1072693248)),168                (fsqrt FPR64:$fj)),169          (FRSQRT_D FPR64:$fj)>;170} // Predicates = [IsLA32]171def : Pat<(fcopysign FPR64:$fj, FPR32:$fk),172          (FCOPYSIGN_D FPR64:$fj, (FCVT_D_S FPR32:$fk))>;173def : Pat<(fcopysign FPR32:$fj, FPR64:$fk),174          (FCOPYSIGN_S FPR32:$fj, (FCVT_S_D FPR64:$fk))>;175def : Pat<(fcanonicalize FPR64:$fj), (FMAX_D $fj, $fj)>;176let Predicates = [IsLA32] in {177def : Pat<(is_fpclass FPR64:$fj, (i32 timm:$mask)),178          (SLTU R0, (ANDI (MOVFR2GR_S_64 (FCLASS_D FPR64:$fj)),179                          (to_fclass_mask timm:$mask)))>;180} // Predicates = [IsLA32]181let Predicates = [IsLA64] in {182def : Pat<(is_fpclass FPR64:$fj, (i32 timm:$mask)),183          (SLTU R0, (ANDI (MOVFR2GR_D (FCLASS_D FPR64:$fj)),184                          (to_fclass_mask timm:$mask)))>;185} // Predicates = [IsLA64]186 187/// Setcc188 189// Match non-signaling comparison190 191// SETOGT/SETOGE/SETUGT/SETUGE/SETGE/SETNE/SETGT will expand into192// SETOLT/SETOLE/SETULT/SETULE/SETLE/SETEQ/SETLT.193def : PatFPSetcc<SETOEQ, FCMP_CEQ_D,  FPR64>;194def : PatFPSetcc<SETEQ,  FCMP_CEQ_D,  FPR64>;195def : PatFPSetcc<SETOLT, FCMP_CLT_D,  FPR64>;196def : PatFPSetcc<SETOLE, FCMP_CLE_D,  FPR64>;197def : PatFPSetcc<SETLE,  FCMP_CLE_D,  FPR64>;198def : PatFPSetcc<SETONE, FCMP_CNE_D,  FPR64>;199def : PatFPSetcc<SETO,   FCMP_COR_D,  FPR64>;200def : PatFPSetcc<SETUEQ, FCMP_CUEQ_D, FPR64>;201def : PatFPSetcc<SETULT, FCMP_CULT_D, FPR64>;202def : PatFPSetcc<SETULE, FCMP_CULE_D, FPR64>;203def : PatFPSetcc<SETUNE, FCMP_CUNE_D, FPR64>;204def : PatFPSetcc<SETUO,  FCMP_CUN_D,  FPR64>;205def : PatFPSetcc<SETLT,  FCMP_CLT_D,  FPR64>;206 207defm : PatFPBrcond<SETOEQ, FCMP_CEQ_D, FPR64>;208defm : PatFPBrcond<SETEQ,  FCMP_CEQ_D, FPR64>;209defm : PatFPBrcond<SETOLT, FCMP_CLT_D, FPR64>;210defm : PatFPBrcond<SETOLE, FCMP_CLE_D, FPR64>;211defm : PatFPBrcond<SETLE,  FCMP_CLE_D, FPR64>;212defm : PatFPBrcond<SETONE, FCMP_CNE_D, FPR64>;213defm : PatFPBrcond<SETO,   FCMP_COR_D, FPR64>;214defm : PatFPBrcond<SETUEQ, FCMP_CUEQ_D, FPR64>;215defm : PatFPBrcond<SETULT, FCMP_CULT_D, FPR64>;216defm : PatFPBrcond<SETULE, FCMP_CULE_D, FPR64>;217defm : PatFPBrcond<SETUNE, FCMP_CUNE_D, FPR64>;218defm : PatFPBrcond<SETUO,  FCMP_CUN_D, FPR64>;219defm : PatFPBrcond<SETLT,  FCMP_CLT_D, FPR64>;220 221// Match signaling comparison222 223def : PatStrictFsetccs<SETOEQ, FCMP_SEQ_D,  FPR64>;224def : PatStrictFsetccs<SETOLT, FCMP_SLT_D,  FPR64>;225def : PatStrictFsetccs<SETOLE, FCMP_SLE_D,  FPR64>;226def : PatStrictFsetccs<SETONE, FCMP_SNE_D,  FPR64>;227def : PatStrictFsetccs<SETO,   FCMP_SOR_D,  FPR64>;228def : PatStrictFsetccs<SETUEQ, FCMP_SUEQ_D, FPR64>;229def : PatStrictFsetccs<SETULT, FCMP_SULT_D, FPR64>;230def : PatStrictFsetccs<SETULE, FCMP_SULE_D, FPR64>;231def : PatStrictFsetccs<SETUNE, FCMP_SUNE_D, FPR64>;232def : PatStrictFsetccs<SETUO,  FCMP_SUN_D,  FPR64>;233def : PatStrictFsetccs<SETLT,  FCMP_SLT_D,  FPR64>;234 235/// Select236 237def : Pat<(select CFR:$cc, FPR64:$fk, FPR64:$fj),238          (FSEL_xD FPR64:$fj, FPR64:$fk, CFR:$cc)>;239 240/// Selectcc241 242def : PatFPSelectcc<SETOEQ, FCMP_CEQ_D,  FSEL_xD, FPR64>;243def : PatFPSelectcc<SETOLT, FCMP_CLT_D,  FSEL_xD, FPR64>;244def : PatFPSelectcc<SETOLE, FCMP_CLE_D,  FSEL_xD, FPR64>;245def : PatFPSelectcc<SETONE, FCMP_CNE_D,  FSEL_xD, FPR64>;246def : PatFPSelectcc<SETO,   FCMP_COR_D,  FSEL_xD, FPR64>;247def : PatFPSelectcc<SETUEQ, FCMP_CUEQ_D, FSEL_xD, FPR64>;248def : PatFPSelectcc<SETULT, FCMP_CULT_D, FSEL_xD, FPR64>;249def : PatFPSelectcc<SETULE, FCMP_CULE_D, FSEL_xD, FPR64>;250def : PatFPSelectcc<SETUNE, FCMP_CUNE_D, FSEL_xD, FPR64>;251def : PatFPSelectcc<SETUO,  FCMP_CUN_D,  FSEL_xD, FPR64>;252 253/// Loads254 255defm : LdPat<load, FLD_D, f64>;256def : RegRegLdPat<load, FLDX_D, f64>;257 258/// Stores259 260defm : StPat<store, FST_D, FPR64, f64>;261def : RegRegStPat<store, FSTX_D, FPR64, f64>;262 263/// FP conversion operations264 265def : Pat<(loongarch_ftint FPR64:$src), (FTINTRZ_W_D FPR64:$src)>;266def : Pat<(f64 (loongarch_ftint FPR64:$src)), (FTINTRZ_L_D FPR64:$src)>;267def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_L_S FPR32:$src)>;268 269// f64 -> f32270def : Pat<(f32 (fpround FPR64:$src)), (FCVT_S_D FPR64:$src)>;271// f32 -> f64272def : Pat<(f64 (fpextend FPR32:$src)), (FCVT_D_S FPR32:$src)>;273 274// FP reciprocal operation275def : Pat<(fdiv fpimm1, FPR64:$src), (FRECIP_D $src)>;276let Predicates = [IsLA32] in {277def : Pat<(fdiv (loongarch_movgr2fr_d_lo_hi (i32 0), (i32 1072693248)), FPR64:$src),278          (FRECIP_D FPR64:$src)>;279} // Predicates = [IsLA32]280 281let Predicates = [HasFrecipe] in {282// FP approximate reciprocal operation283def : Pat<(int_loongarch_frecipe_d FPR64:$src), (FRECIPE_D FPR64:$src)>;284def : Pat<(int_loongarch_frsqrte_d FPR64:$src), (FRSQRTE_D FPR64:$src)>;285def : Pat<(loongarch_frecipe FPR64:$src), (FRECIPE_D FPR64:$src)>;286def : Pat<(loongarch_frsqrte FPR64:$src), (FRSQRTE_D FPR64:$src)>;287}288 289// fmadd.d: fj * fk + fa290def : Pat<(fma FPR64:$fj, FPR64:$fk, FPR64:$fa), (FMADD_D $fj, $fk, $fa)>;291 292// fmsub.d: fj * fk - fa293def : Pat<(fma FPR64:$fj, FPR64:$fk, (fneg FPR64:$fa)),294          (FMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;295 296// fnmadd.d: -(fj * fk + fa)297def : Pat<(fneg (fma FPR64:$fj, FPR64:$fk, FPR64:$fa)),298          (FNMADD_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;299 300// fnmadd.d: -fj * fk - fa (the nsz flag on the FMA)301def : Pat<(fma_nsz (fneg FPR64:$fj), FPR64:$fk, (fneg FPR64:$fa)),302          (FNMADD_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;303 304// fnmsub.d: -(fj * fk - fa)305def : Pat<(fneg (fma FPR64:$fj, FPR64:$fk, (fneg FPR64:$fa))),306          (FNMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;307 308// fnmsub.d: -fj * fk + fa (the nsz flag on the FMA)309def : Pat<(fma_nsz (fneg FPR64:$fj), FPR64:$fk, FPR64:$fa),310          (FNMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;311} // Predicates = [HasBasicD]312 313/// Floating point constants314 315let Predicates = [HasBasicD, IsLA64] in {316def : Pat<(f64 fpimm0), (MOVGR2FR_D R0)>;317def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FR_D R0))>;318def : Pat<(f64 fpimm1), (FFINT_D_L (MOVGR2FR_D (ADDI_D R0, 1)))>;319} // Predicates = [HasBasicD, IsLA64]320let Predicates = [HasBasicD, IsLA32] in {321def : Pat<(f64 fpimm0), (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0)>;322def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0))>;323def : Pat<(f64 fpimm1), (FCVT_D_S (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1))))>;324} // Predicates = [HasBasicD, IsLA32]325 326/// Convert int to FP327 328let Predicates = [HasBasicD, IsLA64] in {329def : Pat<(f32 (sint_to_fp GPR:$src)), (FFINT_S_L (MOVGR2FR_D GPR:$src))>;330def : Pat<(f64 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))),331          (FFINT_D_W (MOVGR2FR_W GPR:$src))>;332def : Pat<(f64 (sint_to_fp GPR:$src)), (FFINT_D_L (MOVGR2FR_D GPR:$src))>;333 334def : Pat<(bitconvert GPR:$src), (MOVGR2FR_D GPR:$src)>;335def : Pat<(loongarch_movgr2fr_d GPR:$src), (MOVGR2FR_D GPR:$src)>;336} // Predicates = [HasBasicD, IsLA64]337let Predicates = [HasBasicD, IsLA32] in {338def : Pat<(f64 (sint_to_fp (i32 GPR:$src))), (FFINT_D_W (MOVGR2FR_W GPR:$src))>;339 340def : Pat<(f64 (loongarch_movgr2fr_d_lo_hi (i32 GPR:$lo), (i32 GPR:$hi))),341          (MOVGR2FRH_W (MOVGR2FR_W_64 GPR:$lo), GPR:$hi)>;342} // Predicates = [HasBasicD, IsLA32]343 344// Convert FP to int345let Predicates = [HasBasicD, IsLA64] in {346def : Pat<(bitconvert FPR64:$src), (MOVFR2GR_D FPR64:$src)>;347} // Predicates = [HasBasicD, IsLA64]348 349// FP Rounding350let Predicates = [HasBasicD, IsLA64] in {351def : PatFpr<frint, FRINT_D, FPR64>;352def : PatFpr<flog2, FLOGB_D, FPR64>;353} // Predicates = [HasBasicD, IsLA64]354 355/// Pseudo-instructions needed for the soft-float ABI with LA32D356 357let Predicates = [HasBasicD, IsLA32] in {358// Moves two GPRs to an FPR.359let usesCustomInserter = 1 in360def BuildPairF64Pseudo361    : Pseudo<(outs FPR64:$dst), (ins GPR:$src1, GPR:$src2),362             [(set FPR64:$dst, (loongarch_build_pair_f64 GPR:$src1, GPR:$src2))]>;363 364// Moves an FPR to two GPRs.365let usesCustomInserter = 1 in366def SplitPairF64Pseudo367    : Pseudo<(outs GPR:$dst1, GPR:$dst2), (ins FPR64:$src),368             [(set GPR:$dst1, GPR:$dst2, (loongarch_split_pair_f64 FPR64:$src))]>;369} // Predicates = [HasBasicD, IsLA32]370