brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.7 KiB · 32954b6 Raw
385 lines · plain
1// LoongArchFloat32InstrInfo.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-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the basic single-precision floating-point instructions.10//11//===----------------------------------------------------------------------===//12 13def NotBoolXor : PatFrags<(ops node:$val),14                          [(xor node:$val, -1), (xor node:$val, 1)]>;15 16//===----------------------------------------------------------------------===//17// LoongArch specific DAG Nodes.18//===----------------------------------------------------------------------===//19 20def SDT_LoongArchMOVGR2FR_W21    : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i32>]>;22def SDT_LoongArchMOVGR2FR_W_LA6423    : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i64>]>;24def SDT_LoongArchMOVFR2GR_S_LA6425    : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, f32>]>;26def SDT_LoongArchFTINT : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;27def SDT_LoongArchFRECIPE : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;28def SDT_LoongArchFRSQRTE : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;29 30// ISD::BRCOND is custom-lowered to LoongArchISD::BRCOND for floating-point31// comparisons to prevent recursive lowering.32def loongarch_brcond : SDNode<"LoongArchISD::BRCOND", SDTBrcond, [SDNPHasChain]>;33 34// FPR<->GPR transfer operations35def loongarch_movgr2fr_w36    : SDNode<"LoongArchISD::MOVGR2FR_W", SDT_LoongArchMOVGR2FR_W>;37def loongarch_movgr2fr_w_la6438    : SDNode<"LoongArchISD::MOVGR2FR_W_LA64", SDT_LoongArchMOVGR2FR_W_LA64>;39def loongarch_movfr2gr_s_la6440    : SDNode<"LoongArchISD::MOVFR2GR_S_LA64", SDT_LoongArchMOVFR2GR_S_LA64>;41 42def loongarch_ftint : SDNode<"LoongArchISD::FTINT", SDT_LoongArchFTINT>;43 44// Floating point approximate reciprocal operation45def loongarch_frecipe : SDNode<"LoongArchISD::FRECIPE", SDT_LoongArchFRECIPE>;46def loongarch_frsqrte : SDNode<"LoongArchISD::FRSQRTE", SDT_LoongArchFRSQRTE>;47 48//===----------------------------------------------------------------------===//49// Instructions50//===----------------------------------------------------------------------===//51 52let Predicates = [HasBasicF] in {53 54// Arithmetic Operation Instructions55def FADD_S : FP_ALU_3R<0x01008000>;56def FSUB_S : FP_ALU_3R<0x01028000>;57def FMUL_S : FP_ALU_3R<0x01048000>;58def FDIV_S : FP_ALU_3R<0x01068000>;59def FMADD_S  : FP_ALU_4R<0x08100000>;60def FMSUB_S  : FP_ALU_4R<0x08500000>;61def FNMADD_S : FP_ALU_4R<0x08900000>;62def FNMSUB_S : FP_ALU_4R<0x08d00000>;63def FMAX_S  : FP_ALU_3R<0x01088000>;64def FMIN_S  : FP_ALU_3R<0x010a8000>;65def FMAXA_S : FP_ALU_3R<0x010c8000>;66def FMINA_S : FP_ALU_3R<0x010e8000>;67def FABS_S   : FP_ALU_2R<0x01140400>;68def FNEG_S   : FP_ALU_2R<0x01141400>;69def FSQRT_S  : FP_ALU_2R<0x01144400>;70def FRECIP_S : FP_ALU_2R<0x01145400>;71def FRSQRT_S : FP_ALU_2R<0x01146400>;72def FRECIPE_S : FP_ALU_2R<0x01147400>;73def FRSQRTE_S : FP_ALU_2R<0x01148400>;74def FSCALEB_S : FP_ALU_3R<0x01108000>;75def FLOGB_S   : FP_ALU_2R<0x01142400>;76def FCOPYSIGN_S : FP_ALU_3R<0x01128000>;77def FCLASS_S  : FP_ALU_2R<0x01143400>;78 79 80// Comparison Instructions81def FCMP_CAF_S  : FP_CMP<0x0c100000>;82def FCMP_CUN_S  : FP_CMP<0x0c140000>;83def FCMP_CEQ_S  : FP_CMP<0x0c120000>;84def FCMP_CUEQ_S : FP_CMP<0x0c160000>;85def FCMP_CLT_S  : FP_CMP<0x0c110000>;86def FCMP_CULT_S : FP_CMP<0x0c150000>;87def FCMP_CLE_S  : FP_CMP<0x0c130000>;88def FCMP_CULE_S : FP_CMP<0x0c170000>;89def FCMP_CNE_S  : FP_CMP<0x0c180000>;90def FCMP_COR_S  : FP_CMP<0x0c1a0000>;91def FCMP_CUNE_S : FP_CMP<0x0c1c0000>;92def FCMP_SAF_S  : FP_CMP<0x0c108000>;93def FCMP_SUN_S  : FP_CMP<0x0c148000>;94def FCMP_SEQ_S  : FP_CMP<0x0c128000>;95def FCMP_SUEQ_S : FP_CMP<0x0c168000>;96def FCMP_SLT_S  : FP_CMP<0x0c118000>;97def FCMP_SULT_S : FP_CMP<0x0c158000>;98def FCMP_SLE_S  : FP_CMP<0x0c138000>;99def FCMP_SULE_S : FP_CMP<0x0c178000>;100def FCMP_SNE_S  : FP_CMP<0x0c188000>;101def FCMP_SOR_S  : FP_CMP<0x0c1a8000>;102def FCMP_SUNE_S : FP_CMP<0x0c1c8000>;103 104// Conversion Instructions105def FFINT_S_W    : FP_CONV<0x011d1000>;106def FTINT_W_S    : FP_CONV<0x011b0400>;107def FTINTRM_W_S  : FP_CONV<0x011a0400>;108def FTINTRP_W_S  : FP_CONV<0x011a4400>;109def FTINTRZ_W_S  : FP_CONV<0x011a8400>;110def FTINTRNE_W_S : FP_CONV<0x011ac400>;111def FRINT_S      : FP_CONV<0x011e4400>;112 113// Move Instructions114def FSEL_xS    : FP_SEL<0x0d000000>;115def FMOV_S     : FP_MOV<0x01149400>;116def MOVGR2FR_W : FP_MOV<0x0114a400, FPR32, GPR>;117def MOVFR2GR_S : FP_MOV<0x0114b400, GPR, FPR32>;118let hasSideEffects = 1 in {119def MOVGR2FCSR : FP_MOV<0x0114c000, FCSR, GPR>;120def MOVFCSR2GR : FP_MOV<0x0114c800, GPR, FCSR>;121} // hasSideEffects = 1122def MOVFR2CF_xS : FP_MOV<0x0114d000, CFR, FPR32>;123def MOVCF2FR_xS : FP_MOV<0x0114d400, FPR32, CFR>;124def MOVGR2CF    : FP_MOV<0x0114d800, CFR, GPR>;125def MOVCF2GR    : FP_MOV<0x0114dc00, GPR, CFR>;126 127// Branch Instructions128def BCEQZ : FP_BRANCH<0x48000000>;129def BCNEZ : FP_BRANCH<0x48000100>;130 131// Common Memory Access Instructions132def FLD_S : FP_LOAD_2RI12<0x2b000000>;133def FST_S : FP_STORE_2RI12<0x2b400000>;134def FLDX_S : FP_LOAD_3R<0x38300000>;135def FSTX_S : FP_STORE_3R<0x38380000>;136 137// Bound Check Memory Access Instructions138def FLDGT_S : FP_LOAD_3R<0x38740000>;139def FLDLE_S : FP_LOAD_3R<0x38750000>;140def FSTGT_S : FP_STORE_3R<0x38760000>;141def FSTLE_S : FP_STORE_3R<0x38770000>;142 143// Pseudo instructions for spill/reload CFRs.144let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in145def PseudoST_CFR : Pseudo<(outs),146                          (ins CFR:$ccd, GPR:$rj, grlenimm:$imm)>;147let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in148def PseudoLD_CFR : Pseudo<(outs CFR:$ccd),149                          (ins GPR:$rj, grlenimm:$imm)>;150 151// SET_CFR_{FALSE,TRUE}152// These instructions are defined in order to avoid expensive check error if153// regular instruction patterns are used.154// fcmp.caf.s $dst, $fa0, $fa0155def SET_CFR_FALSE : SET_CFR<0x0c100000, "fcmp.caf.s">;156// fcmp.cueq.s $dst, $fa0, $fa0157def SET_CFR_TRUE  : SET_CFR<0x0c160000, "fcmp.cueq.s">;158 159// Pseudo instruction for copying CFRs.160def PseudoCopyCFR : Pseudo<(outs CFR:$dst), (ins CFR:$src)> {161  let mayLoad = 0;162  let mayStore = 0;163  let hasSideEffects = 0;164  let Size = 12;165}166 167} // Predicates = [HasBasicF]168 169//===----------------------------------------------------------------------===//170// Pseudo-instructions and codegen patterns171//===----------------------------------------------------------------------===//172 173/// Generic pattern classes174 175class PatFpr<SDPatternOperator OpNode, LAInst Inst, RegisterClass RegTy>176    : Pat<(OpNode RegTy:$fj), (Inst $fj)>;177class PatFprFpr<SDPatternOperator OpNode, LAInst Inst, RegisterClass RegTy>178    : Pat<(OpNode RegTy:$fj, RegTy:$fk), (Inst $fj, $fk)>;179 180let Predicates = [HasBasicF] in {181 182/// Float arithmetic operations183 184def : PatFprFpr<fadd, FADD_S, FPR32>;185def : PatFprFpr<fsub, FSUB_S, FPR32>;186def : PatFprFpr<fmul, FMUL_S, FPR32>;187def : PatFprFpr<fdiv, FDIV_S, FPR32>;188def : PatFprFpr<fcopysign, FCOPYSIGN_S, FPR32>;189def : PatFprFpr<fmaxnum_ieee, FMAX_S, FPR32>;190def : PatFprFpr<fmaxnum, FMAX_S, FPR32>;191def : PatFprFpr<fminnum_ieee, FMIN_S, FPR32>;192def : PatFprFpr<fminnum, FMIN_S, FPR32>;193def : PatFpr<fneg, FNEG_S, FPR32>;194def : PatFpr<fabs, FABS_S, FPR32>;195def : PatFpr<fsqrt, FSQRT_S, FPR32>;196def : Pat<(fdiv fpimm1, (fsqrt FPR32:$fj)), (FRSQRT_S FPR32:$fj)>;197let Predicates = [HasBasicF, IsLA64] in {198def : Pat<(fdiv (loongarch_movgr2fr_w_la64 (i64 1065353216)), (fsqrt FPR32:$fj)),199          (FRSQRT_S FPR32:$fj)>;200} // Predicates = [HasBasicF, IsLA64]201let Predicates = [HasBasicF, IsLA32] in {202def : Pat<(fdiv (loongarch_movgr2fr_w (i32 1065353216)), (fsqrt FPR32:$fj)),203          (FRSQRT_S FPR32:$fj)>;204} // Predicates = [HasBasicF, IsLA32]205def : Pat<(fcanonicalize FPR32:$fj), (FMAX_S $fj, $fj)>;206def : Pat<(is_fpclass FPR32:$fj, (i32 timm:$mask)),207          (SLTU R0, (ANDI (MOVFR2GR_S (FCLASS_S FPR32:$fj)),208                          (to_fclass_mask timm:$mask)))>;209 210/// Setcc211 212// Match non-signaling comparison213 214class PatFPSetcc<CondCode cc, LAInst CmpInst, RegisterClass RegTy>215    : Pat<(any_fsetcc RegTy:$fj, RegTy:$fk, cc),216          (CmpInst RegTy:$fj, RegTy:$fk)>;217// SETOGT/SETOGE/SETUGT/SETUGE/SETGE/SETNE/SETGT will expand into218// SETOLT/SETOLE/SETULT/SETULE/SETLE/SETEQ/SETLT.219def : PatFPSetcc<SETOEQ, FCMP_CEQ_S,  FPR32>;220def : PatFPSetcc<SETEQ,  FCMP_CEQ_S,  FPR32>;221def : PatFPSetcc<SETOLT, FCMP_CLT_S,  FPR32>;222def : PatFPSetcc<SETOLE, FCMP_CLE_S,  FPR32>;223def : PatFPSetcc<SETLE,  FCMP_CLE_S,  FPR32>;224def : PatFPSetcc<SETONE, FCMP_CNE_S,  FPR32>;225def : PatFPSetcc<SETO,   FCMP_COR_S,  FPR32>;226def : PatFPSetcc<SETUEQ, FCMP_CUEQ_S, FPR32>;227def : PatFPSetcc<SETULT, FCMP_CULT_S, FPR32>;228def : PatFPSetcc<SETULE, FCMP_CULE_S, FPR32>;229def : PatFPSetcc<SETUNE, FCMP_CUNE_S, FPR32>;230def : PatFPSetcc<SETUO,  FCMP_CUN_S,  FPR32>;231def : PatFPSetcc<SETLT,  FCMP_CLT_S,  FPR32>;232 233multiclass PatFPBrcond<CondCode cc, LAInst CmpInst, RegisterClass RegTy> {234  def : Pat<(loongarch_brcond (NotBoolXor (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc))),235                              bb:$imm21),236            (BCEQZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>;237  def : Pat<(loongarch_brcond (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), bb:$imm21),238            (BCNEZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>;239}240 241defm : PatFPBrcond<SETOEQ, FCMP_CEQ_S, FPR32>;242defm : PatFPBrcond<SETEQ , FCMP_CEQ_S, FPR32>;243defm : PatFPBrcond<SETOLT, FCMP_CLT_S, FPR32>;244defm : PatFPBrcond<SETOLE, FCMP_CLE_S, FPR32>;245defm : PatFPBrcond<SETLE,  FCMP_CLE_S, FPR32>;246defm : PatFPBrcond<SETONE, FCMP_CNE_S, FPR32>;247defm : PatFPBrcond<SETO,   FCMP_COR_S, FPR32>;248defm : PatFPBrcond<SETUEQ, FCMP_CUEQ_S, FPR32>;249defm : PatFPBrcond<SETULT, FCMP_CULT_S, FPR32>;250defm : PatFPBrcond<SETULE, FCMP_CULE_S, FPR32>;251defm : PatFPBrcond<SETUNE, FCMP_CUNE_S, FPR32>;252defm : PatFPBrcond<SETUO,  FCMP_CUN_S, FPR32>;253defm : PatFPBrcond<SETLT,  FCMP_CLT_S, FPR32>;254 255// Match signaling comparison256 257class PatStrictFsetccs<CondCode cc, LAInst CmpInst, RegisterClass RegTy>258    : Pat<(strict_fsetccs RegTy:$fj, RegTy:$fk, cc),259          (CmpInst RegTy:$fj, RegTy:$fk)>;260def : PatStrictFsetccs<SETOEQ, FCMP_SEQ_S,  FPR32>;261def : PatStrictFsetccs<SETOLT, FCMP_SLT_S,  FPR32>;262def : PatStrictFsetccs<SETOLE, FCMP_SLE_S,  FPR32>;263def : PatStrictFsetccs<SETONE, FCMP_SNE_S,  FPR32>;264def : PatStrictFsetccs<SETO,   FCMP_SOR_S,  FPR32>;265def : PatStrictFsetccs<SETUEQ, FCMP_SUEQ_S, FPR32>;266def : PatStrictFsetccs<SETULT, FCMP_SULT_S, FPR32>;267def : PatStrictFsetccs<SETULE, FCMP_SULE_S, FPR32>;268def : PatStrictFsetccs<SETUNE, FCMP_SUNE_S, FPR32>;269def : PatStrictFsetccs<SETUO,  FCMP_SUN_S,  FPR32>;270def : PatStrictFsetccs<SETLT,  FCMP_SLT_S,  FPR32>;271 272/// Select273 274def : Pat<(select CFR:$cc, FPR32:$fk, FPR32:$fj),275          (FSEL_xS FPR32:$fj, FPR32:$fk, CFR:$cc)>;276 277/// Selectcc278 279class PatFPSelectcc<CondCode cc, LAInst CmpInst, LAInst SelInst,280                    RegisterClass RegTy>281    : Pat<(select (GRLenVT (setcc RegTy:$a, RegTy:$b, cc)), RegTy:$t, RegTy:$f),282          (SelInst RegTy:$f, RegTy:$t, (CmpInst RegTy:$a, RegTy:$b))>;283def : PatFPSelectcc<SETOEQ, FCMP_CEQ_S,  FSEL_xS, FPR32>;284def : PatFPSelectcc<SETOLT, FCMP_CLT_S,  FSEL_xS, FPR32>;285def : PatFPSelectcc<SETOLE, FCMP_CLE_S,  FSEL_xS, FPR32>;286def : PatFPSelectcc<SETONE, FCMP_CNE_S,  FSEL_xS, FPR32>;287def : PatFPSelectcc<SETO,   FCMP_COR_S,  FSEL_xS, FPR32>;288def : PatFPSelectcc<SETUEQ, FCMP_CUEQ_S, FSEL_xS, FPR32>;289def : PatFPSelectcc<SETULT, FCMP_CULT_S, FSEL_xS, FPR32>;290def : PatFPSelectcc<SETULE, FCMP_CULE_S, FSEL_xS, FPR32>;291def : PatFPSelectcc<SETUNE, FCMP_CUNE_S, FSEL_xS, FPR32>;292def : PatFPSelectcc<SETUO,  FCMP_CUN_S,  FSEL_xS, FPR32>;293 294/// Loads295 296defm : LdPat<load, FLD_S, f32>;297def : RegRegLdPat<load, FLDX_S, f32>;298 299/// Stores300 301defm : StPat<store, FST_S, FPR32, f32>;302def : RegRegStPat<store, FSTX_S, FPR32, f32>;303 304/// Floating point constants305 306def : Pat<(f32 fpimm0), (MOVGR2FR_W R0)>;307def : Pat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W R0))>;308def : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>;309 310// FP Conversion311def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_W_S FPR32:$src)>;312 313// FP reciprocal operation314def : Pat<(fdiv fpimm1, FPR32:$src), (FRECIP_S $src)>;315let Predicates = [HasBasicF, IsLA64] in {316def : Pat<(fdiv (loongarch_movgr2fr_w_la64 (i64 1065353216)), FPR32:$src),317          (FRECIP_S $src)>;318} // Predicates = [HasBasicF, IsLA64]319let Predicates = [HasBasicF, IsLA32] in {320def : Pat<(fdiv (loongarch_movgr2fr_w (i32 1065353216)), FPR32:$src),321          (FRECIP_S $src)>;322} // Predicates = [HasBasicF, IsLA32]323 324let Predicates = [HasFrecipe] in {325// FP approximate reciprocal operation326def : Pat<(int_loongarch_frecipe_s FPR32:$src), (FRECIPE_S FPR32:$src)>;327def : Pat<(int_loongarch_frsqrte_s FPR32:$src), (FRSQRTE_S FPR32:$src)>;328def : Pat<(loongarch_frecipe FPR32:$src), (FRECIPE_S FPR32:$src)>;329def : Pat<(loongarch_frsqrte FPR32:$src), (FRSQRTE_S FPR32:$src)>;330}331 332// fmadd.s: fj * fk + fa333def : Pat<(fma FPR32:$fj, FPR32:$fk, FPR32:$fa), (FMADD_S $fj, $fk, $fa)>;334 335// fmsub.s: fj * fk - fa336def : Pat<(fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa)),337          (FMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;338 339// fnmadd.s: -(fj * fk + fa)340def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, FPR32:$fa)),341          (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;342 343// fnmadd.s: -fj * fk - fa (the nsz flag on the FMA)344def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, (fneg FPR32:$fa)),345          (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;346 347// fnmsub.s: -(fj * fk - fa)348def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa))),349          (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;350 351// fnmsub.s: -fj * fk + fa (the nsz flag on the FMA)352def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, FPR32:$fa),353          (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;354} // Predicates = [HasBasicF]355 356let Predicates = [HasBasicF, IsLA64] in {357// GPR -> FPR358def : Pat<(loongarch_movgr2fr_w_la64 GPR:$src), (MOVGR2FR_W GPR:$src)>;359// FPR -> GPR360def : Pat<(loongarch_movfr2gr_s_la64 FPR32:$src),361          (MOVFR2GR_S FPR32:$src)>;362// int -> f32363def : Pat<(f32 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))),364          (FFINT_S_W (MOVGR2FR_W GPR:$src))>;365// uint -> f32366def : Pat<(f32 (uint_to_fp (i64 (sexti32 (i64 GPR:$src))))),367          (FFINT_S_W (MOVGR2FR_W GPR:$src))>;368} // Predicates = [HasBasicF, IsLA64]369 370// FP Rounding371let Predicates = [HasBasicF, IsLA64] in {372def : PatFpr<frint, FRINT_S, FPR32>;373def : PatFpr<flog2, FLOGB_S, FPR32>;374} // Predicates = [HasBasicF, IsLA64]375 376let Predicates = [HasBasicF, IsLA32] in {377// GPR -> FPR378def : Pat<(bitconvert (i32 GPR:$src)), (MOVGR2FR_W GPR:$src)>;379def : Pat<(loongarch_movgr2fr_w (i32 GPR:$src)), (MOVGR2FR_W GPR:$src)>;380// FPR -> GPR381def : Pat<(i32 (bitconvert FPR32:$src)), (MOVFR2GR_S FPR32:$src)>;382// int -> f32383def : Pat<(f32 (sint_to_fp (i32 GPR:$src))), (FFINT_S_W (MOVGR2FR_W GPR:$src))>;384} // Predicates = [HasBasicF, IsLA32]385