xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
106c3fb27SDimitry Andric// LoongArchFloat32InstrInfo.td - Single-Precision Float instr --*- tablegen -*-
281ad6265SDimitry Andric//
381ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric//
781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
881ad6265SDimitry Andric//
981ad6265SDimitry Andric// This file describes the baisc single-precision floating-point instructions.
1081ad6265SDimitry Andric//
1181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
1281ad6265SDimitry Andric
1381ad6265SDimitry Andric//===----------------------------------------------------------------------===//
14753f127fSDimitry Andric// LoongArch specific DAG Nodes.
15753f127fSDimitry Andric//===----------------------------------------------------------------------===//
16753f127fSDimitry Andric
17753f127fSDimitry Andricdef SDT_LoongArchMOVGR2FR_W_LA64
18753f127fSDimitry Andric    : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i64>]>;
19753f127fSDimitry Andricdef SDT_LoongArchMOVFR2GR_S_LA64
20753f127fSDimitry Andric    : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, f32>]>;
21753f127fSDimitry Andricdef SDT_LoongArchFTINT : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
22753f127fSDimitry Andric
23753f127fSDimitry Andricdef loongarch_movgr2fr_w_la64
24753f127fSDimitry Andric    : SDNode<"LoongArchISD::MOVGR2FR_W_LA64", SDT_LoongArchMOVGR2FR_W_LA64>;
25753f127fSDimitry Andricdef loongarch_movfr2gr_s_la64
26753f127fSDimitry Andric    : SDNode<"LoongArchISD::MOVFR2GR_S_LA64", SDT_LoongArchMOVFR2GR_S_LA64>;
27753f127fSDimitry Andricdef loongarch_ftint : SDNode<"LoongArchISD::FTINT", SDT_LoongArchFTINT>;
28753f127fSDimitry Andric
29753f127fSDimitry Andric//===----------------------------------------------------------------------===//
3081ad6265SDimitry Andric// Instructions
3181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
3281ad6265SDimitry Andric
3381ad6265SDimitry Andriclet Predicates = [HasBasicF] in {
3481ad6265SDimitry Andric
3581ad6265SDimitry Andric// Arithmetic Operation Instructions
3606c3fb27SDimitry Andricdef FADD_S : FP_ALU_3R<0x01008000>;
3706c3fb27SDimitry Andricdef FSUB_S : FP_ALU_3R<0x01028000>;
3806c3fb27SDimitry Andricdef FMUL_S : FP_ALU_3R<0x01048000>;
3906c3fb27SDimitry Andricdef FDIV_S : FP_ALU_3R<0x01068000>;
4006c3fb27SDimitry Andricdef FMADD_S  : FP_ALU_4R<0x08100000>;
4106c3fb27SDimitry Andricdef FMSUB_S  : FP_ALU_4R<0x08500000>;
4206c3fb27SDimitry Andricdef FNMADD_S : FP_ALU_4R<0x08900000>;
4306c3fb27SDimitry Andricdef FNMSUB_S : FP_ALU_4R<0x08d00000>;
4406c3fb27SDimitry Andricdef FMAX_S  : FP_ALU_3R<0x01088000>;
4506c3fb27SDimitry Andricdef FMIN_S  : FP_ALU_3R<0x010a8000>;
4606c3fb27SDimitry Andricdef FMAXA_S : FP_ALU_3R<0x010c8000>;
4706c3fb27SDimitry Andricdef FMINA_S : FP_ALU_3R<0x010e8000>;
4806c3fb27SDimitry Andricdef FABS_S   : FP_ALU_2R<0x01140400>;
4906c3fb27SDimitry Andricdef FNEG_S   : FP_ALU_2R<0x01141400>;
5006c3fb27SDimitry Andricdef FSQRT_S  : FP_ALU_2R<0x01144400>;
5106c3fb27SDimitry Andricdef FRECIP_S : FP_ALU_2R<0x01145400>;
5206c3fb27SDimitry Andricdef FRSQRT_S : FP_ALU_2R<0x01146400>;
53*7a6dacacSDimitry Andricdef FRECIPE_S : FP_ALU_2R<0x01147400>;
54*7a6dacacSDimitry Andricdef FRSQRTE_S : FP_ALU_2R<0x01148400>;
5506c3fb27SDimitry Andricdef FSCALEB_S : FP_ALU_3R<0x01108000>;
5606c3fb27SDimitry Andricdef FLOGB_S   : FP_ALU_2R<0x01142400>;
5706c3fb27SDimitry Andricdef FCOPYSIGN_S : FP_ALU_3R<0x01128000>;
5806c3fb27SDimitry Andricdef FCLASS_S  : FP_ALU_2R<0x01143400>;
5981ad6265SDimitry Andric
6081ad6265SDimitry Andric
6181ad6265SDimitry Andric// Comparison Instructions
6206c3fb27SDimitry Andricdef FCMP_CAF_S  : FP_CMP<0x0c100000>;
6306c3fb27SDimitry Andricdef FCMP_CUN_S  : FP_CMP<0x0c140000>;
6406c3fb27SDimitry Andricdef FCMP_CEQ_S  : FP_CMP<0x0c120000>;
6506c3fb27SDimitry Andricdef FCMP_CUEQ_S : FP_CMP<0x0c160000>;
6606c3fb27SDimitry Andricdef FCMP_CLT_S  : FP_CMP<0x0c110000>;
6706c3fb27SDimitry Andricdef FCMP_CULT_S : FP_CMP<0x0c150000>;
6806c3fb27SDimitry Andricdef FCMP_CLE_S  : FP_CMP<0x0c130000>;
6906c3fb27SDimitry Andricdef FCMP_CULE_S : FP_CMP<0x0c170000>;
7006c3fb27SDimitry Andricdef FCMP_CNE_S  : FP_CMP<0x0c180000>;
7106c3fb27SDimitry Andricdef FCMP_COR_S  : FP_CMP<0x0c1a0000>;
7206c3fb27SDimitry Andricdef FCMP_CUNE_S : FP_CMP<0x0c1c0000>;
7306c3fb27SDimitry Andricdef FCMP_SAF_S  : FP_CMP<0x0c108000>;
7406c3fb27SDimitry Andricdef FCMP_SUN_S  : FP_CMP<0x0c148000>;
7506c3fb27SDimitry Andricdef FCMP_SEQ_S  : FP_CMP<0x0c128000>;
7606c3fb27SDimitry Andricdef FCMP_SUEQ_S : FP_CMP<0x0c168000>;
7706c3fb27SDimitry Andricdef FCMP_SLT_S  : FP_CMP<0x0c118000>;
7806c3fb27SDimitry Andricdef FCMP_SULT_S : FP_CMP<0x0c158000>;
7906c3fb27SDimitry Andricdef FCMP_SLE_S  : FP_CMP<0x0c138000>;
8006c3fb27SDimitry Andricdef FCMP_SULE_S : FP_CMP<0x0c178000>;
8106c3fb27SDimitry Andricdef FCMP_SNE_S  : FP_CMP<0x0c188000>;
8206c3fb27SDimitry Andricdef FCMP_SOR_S  : FP_CMP<0x0c1a8000>;
8306c3fb27SDimitry Andricdef FCMP_SUNE_S : FP_CMP<0x0c1c8000>;
8481ad6265SDimitry Andric
8581ad6265SDimitry Andric// Conversion Instructions
8606c3fb27SDimitry Andricdef FFINT_S_W    : FP_CONV<0x011d1000>;
8706c3fb27SDimitry Andricdef FTINT_W_S    : FP_CONV<0x011b0400>;
8806c3fb27SDimitry Andricdef FTINTRM_W_S  : FP_CONV<0x011a0400>;
8906c3fb27SDimitry Andricdef FTINTRP_W_S  : FP_CONV<0x011a4400>;
9006c3fb27SDimitry Andricdef FTINTRZ_W_S  : FP_CONV<0x011a8400>;
9106c3fb27SDimitry Andricdef FTINTRNE_W_S : FP_CONV<0x011ac400>;
9206c3fb27SDimitry Andricdef FRINT_S      : FP_CONV<0x011e4400>;
9381ad6265SDimitry Andric
9481ad6265SDimitry Andric// Move Instructions
9506c3fb27SDimitry Andricdef FSEL_xS    : FP_SEL<0x0d000000>;
9606c3fb27SDimitry Andricdef FMOV_S     : FP_MOV<0x01149400>;
9706c3fb27SDimitry Andricdef MOVGR2FR_W : FP_MOV<0x0114a400, FPR32, GPR>;
9806c3fb27SDimitry Andricdef MOVFR2GR_S : FP_MOV<0x0114b400, GPR, FPR32>;
9906c3fb27SDimitry Andriclet hasSideEffects = 1 in {
10006c3fb27SDimitry Andricdef MOVGR2FCSR : FP_MOV<0x0114c000, FCSR, GPR>;
10106c3fb27SDimitry Andricdef MOVFCSR2GR : FP_MOV<0x0114c800, GPR, FCSR>;
10206c3fb27SDimitry Andric} // hasSideEffects = 1
10306c3fb27SDimitry Andricdef MOVFR2CF_xS : FP_MOV<0x0114d000, CFR, FPR32>;
10406c3fb27SDimitry Andricdef MOVCF2FR_xS : FP_MOV<0x0114d400, FPR32, CFR>;
10506c3fb27SDimitry Andricdef MOVGR2CF    : FP_MOV<0x0114d800, CFR, GPR>;
10606c3fb27SDimitry Andricdef MOVCF2GR    : FP_MOV<0x0114dc00, GPR, CFR>;
10781ad6265SDimitry Andric
10881ad6265SDimitry Andric// Branch Instructions
10906c3fb27SDimitry Andricdef BCEQZ : FP_BRANCH<0x48000000>;
11006c3fb27SDimitry Andricdef BCNEZ : FP_BRANCH<0x48000100>;
11181ad6265SDimitry Andric
11281ad6265SDimitry Andric// Common Memory Access Instructions
11306c3fb27SDimitry Andricdef FLD_S : FP_LOAD_2RI12<0x2b000000>;
11406c3fb27SDimitry Andricdef FST_S : FP_STORE_2RI12<0x2b400000>;
11506c3fb27SDimitry Andricdef FLDX_S : FP_LOAD_3R<0x38300000>;
11606c3fb27SDimitry Andricdef FSTX_S : FP_STORE_3R<0x38380000>;
11781ad6265SDimitry Andric
11881ad6265SDimitry Andric// Bound Check Memory Access Instructions
11906c3fb27SDimitry Andricdef FLDGT_S : FP_LOAD_3R<0x38740000>;
12006c3fb27SDimitry Andricdef FLDLE_S : FP_LOAD_3R<0x38750000>;
12106c3fb27SDimitry Andricdef FSTGT_S : FP_STORE_3R<0x38760000>;
12206c3fb27SDimitry Andricdef FSTLE_S : FP_STORE_3R<0x38770000>;
12381ad6265SDimitry Andric
124bdd1243dSDimitry Andric// Pseudo instructions for spill/reload CFRs.
125bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
126bdd1243dSDimitry Andricdef PseudoST_CFR : Pseudo<(outs),
127bdd1243dSDimitry Andric                          (ins CFR:$ccd, GPR:$rj, grlenimm:$imm)>;
128bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
129bdd1243dSDimitry Andricdef PseudoLD_CFR : Pseudo<(outs CFR:$ccd),
130bdd1243dSDimitry Andric                          (ins GPR:$rj, grlenimm:$imm)>;
131b121cb00SDimitry Andric
132b121cb00SDimitry Andric// SET_CFR_{FALSE,TRUE}
133b121cb00SDimitry Andric// These instructions are defined in order to avoid expensive check error if
134b121cb00SDimitry Andric// regular instruction patterns are used.
135b121cb00SDimitry Andric// fcmp.caf.s $dst, $fa0, $fa0
136b121cb00SDimitry Andricdef SET_CFR_FALSE : SET_CFR<0x0c100000, "fcmp.caf.s">;
137b121cb00SDimitry Andric// fcmp.cueq.s $dst, $fa0, $fa0
138b121cb00SDimitry Andricdef SET_CFR_TRUE  : SET_CFR<0x0c160000, "fcmp.cueq.s">;
139b121cb00SDimitry Andric
140b121cb00SDimitry Andric// Pseudo instruction for copying CFRs.
141b121cb00SDimitry Andricdef PseudoCopyCFR : Pseudo<(outs CFR:$dst), (ins CFR:$src)> {
142b121cb00SDimitry Andric  let mayLoad = 0;
143b121cb00SDimitry Andric  let mayStore = 0;
144b121cb00SDimitry Andric  let hasSideEffects = 0;
145b121cb00SDimitry Andric  let Size = 12;
146b121cb00SDimitry Andric}
147b121cb00SDimitry Andric
14881ad6265SDimitry Andric} // Predicates = [HasBasicF]
14981ad6265SDimitry Andric
15081ad6265SDimitry Andric//===----------------------------------------------------------------------===//
15181ad6265SDimitry Andric// Pseudo-instructions and codegen patterns
15281ad6265SDimitry Andric//===----------------------------------------------------------------------===//
15381ad6265SDimitry Andric
15481ad6265SDimitry Andric/// Generic pattern classes
15581ad6265SDimitry Andric
15681ad6265SDimitry Andricclass PatFpr<SDPatternOperator OpNode, LAInst Inst, RegisterClass RegTy>
15781ad6265SDimitry Andric    : Pat<(OpNode RegTy:$fj), (Inst $fj)>;
15881ad6265SDimitry Andricclass PatFprFpr<SDPatternOperator OpNode, LAInst Inst, RegisterClass RegTy>
15981ad6265SDimitry Andric    : Pat<(OpNode RegTy:$fj, RegTy:$fk), (Inst $fj, $fk)>;
16081ad6265SDimitry Andric
16181ad6265SDimitry Andriclet Predicates = [HasBasicF] in {
16281ad6265SDimitry Andric
16381ad6265SDimitry Andric/// Float arithmetic operations
16481ad6265SDimitry Andric
16581ad6265SDimitry Andricdef : PatFprFpr<fadd, FADD_S, FPR32>;
16681ad6265SDimitry Andricdef : PatFprFpr<fsub, FSUB_S, FPR32>;
16781ad6265SDimitry Andricdef : PatFprFpr<fmul, FMUL_S, FPR32>;
16881ad6265SDimitry Andricdef : PatFprFpr<fdiv, FDIV_S, FPR32>;
169bdd1243dSDimitry Andricdef : PatFprFpr<fcopysign, FCOPYSIGN_S, FPR32>;
170bdd1243dSDimitry Andricdef : PatFprFpr<fmaxnum_ieee, FMAX_S, FPR32>;
171bdd1243dSDimitry Andricdef : PatFprFpr<fminnum_ieee, FMIN_S, FPR32>;
17281ad6265SDimitry Andricdef : PatFpr<fneg, FNEG_S, FPR32>;
173bdd1243dSDimitry Andricdef : PatFpr<fabs, FABS_S, FPR32>;
174bdd1243dSDimitry Andricdef : PatFpr<fsqrt, FSQRT_S, FPR32>;
175bdd1243dSDimitry Andricdef : Pat<(fdiv fpimm1, (fsqrt FPR32:$fj)), (FRSQRT_S FPR32:$fj)>;
176bdd1243dSDimitry Andricdef : Pat<(fcanonicalize FPR32:$fj), (FMAX_S $fj, $fj)>;
1775f757f3fSDimitry Andricdef : Pat<(is_fpclass FPR32:$fj, (i32 timm:$mask)),
1785f757f3fSDimitry Andric          (SLTU R0, (ANDI (MOVFR2GR_S (FCLASS_S FPR32:$fj)),
1795f757f3fSDimitry Andric                          (to_fclass_mask timm:$mask)))>;
18081ad6265SDimitry Andric
18181ad6265SDimitry Andric/// Setcc
18281ad6265SDimitry Andric
18381ad6265SDimitry Andric// Match non-signaling comparison
18481ad6265SDimitry Andric
18581ad6265SDimitry Andricclass PatFPSetcc<CondCode cc, LAInst CmpInst, RegisterClass RegTy>
186bdd1243dSDimitry Andric    : Pat<(any_fsetcc RegTy:$fj, RegTy:$fk, cc),
187bdd1243dSDimitry Andric          (CmpInst RegTy:$fj, RegTy:$fk)>;
188bdd1243dSDimitry Andric// SETOGT/SETOGE/SETUGT/SETUGE/SETGE/SETNE/SETGT will expand into
189bdd1243dSDimitry Andric// SETOLT/SETOLE/SETULT/SETULE/SETLE/SETEQ/SETLT.
19081ad6265SDimitry Andricdef : PatFPSetcc<SETOEQ, FCMP_CEQ_S,  FPR32>;
191bdd1243dSDimitry Andricdef : PatFPSetcc<SETEQ,  FCMP_CEQ_S,  FPR32>;
19281ad6265SDimitry Andricdef : PatFPSetcc<SETOLT, FCMP_CLT_S,  FPR32>;
19381ad6265SDimitry Andricdef : PatFPSetcc<SETOLE, FCMP_CLE_S,  FPR32>;
194bdd1243dSDimitry Andricdef : PatFPSetcc<SETLE,  FCMP_CLE_S,  FPR32>;
19581ad6265SDimitry Andricdef : PatFPSetcc<SETONE, FCMP_CNE_S,  FPR32>;
19681ad6265SDimitry Andricdef : PatFPSetcc<SETO,   FCMP_COR_S,  FPR32>;
19781ad6265SDimitry Andricdef : PatFPSetcc<SETUEQ, FCMP_CUEQ_S, FPR32>;
19881ad6265SDimitry Andricdef : PatFPSetcc<SETULT, FCMP_CULT_S, FPR32>;
19981ad6265SDimitry Andricdef : PatFPSetcc<SETULE, FCMP_CULE_S, FPR32>;
20081ad6265SDimitry Andricdef : PatFPSetcc<SETUNE, FCMP_CUNE_S, FPR32>;
20181ad6265SDimitry Andricdef : PatFPSetcc<SETUO,  FCMP_CUN_S,  FPR32>;
202753f127fSDimitry Andricdef : PatFPSetcc<SETLT,  FCMP_CLT_S,  FPR32>;
20381ad6265SDimitry Andric
204bdd1243dSDimitry Andricmulticlass PatFPBrcond<CondCode cc, LAInst CmpInst, RegisterClass RegTy> {
205bdd1243dSDimitry Andric  def : Pat<(brcond (xor (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), -1),
206bdd1243dSDimitry Andric                     bb:$imm21),
207bdd1243dSDimitry Andric            (BCEQZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>;
208bdd1243dSDimitry Andric  def : Pat<(brcond (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), bb:$imm21),
209bdd1243dSDimitry Andric            (BCNEZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>;
210bdd1243dSDimitry Andric}
211bdd1243dSDimitry Andric
212bdd1243dSDimitry Andricdefm : PatFPBrcond<SETOEQ, FCMP_CEQ_S, FPR32>;
213bdd1243dSDimitry Andricdefm : PatFPBrcond<SETOLT, FCMP_CLT_S, FPR32>;
214bdd1243dSDimitry Andricdefm : PatFPBrcond<SETOLE, FCMP_CLE_S, FPR32>;
215bdd1243dSDimitry Andricdefm : PatFPBrcond<SETONE, FCMP_CNE_S, FPR32>;
216bdd1243dSDimitry Andricdefm : PatFPBrcond<SETO,   FCMP_COR_S, FPR32>;
217bdd1243dSDimitry Andricdefm : PatFPBrcond<SETUEQ, FCMP_CUEQ_S, FPR32>;
218bdd1243dSDimitry Andricdefm : PatFPBrcond<SETULT, FCMP_CULT_S, FPR32>;
219bdd1243dSDimitry Andricdefm : PatFPBrcond<SETULE, FCMP_CULE_S, FPR32>;
220bdd1243dSDimitry Andricdefm : PatFPBrcond<SETUNE, FCMP_CUNE_S, FPR32>;
221bdd1243dSDimitry Andricdefm : PatFPBrcond<SETUO,  FCMP_CUN_S, FPR32>;
222bdd1243dSDimitry Andricdefm : PatFPBrcond<SETLT,  FCMP_CLT_S, FPR32>;
223bdd1243dSDimitry Andric
224bdd1243dSDimitry Andric// Match signaling comparison
225bdd1243dSDimitry Andric
226bdd1243dSDimitry Andricclass PatStrictFsetccs<CondCode cc, LAInst CmpInst, RegisterClass RegTy>
227bdd1243dSDimitry Andric    : Pat<(strict_fsetccs RegTy:$fj, RegTy:$fk, cc),
228bdd1243dSDimitry Andric          (CmpInst RegTy:$fj, RegTy:$fk)>;
229bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETOEQ, FCMP_SEQ_S,  FPR32>;
230bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETOLT, FCMP_SLT_S,  FPR32>;
231bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETOLE, FCMP_SLE_S,  FPR32>;
232bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETONE, FCMP_SNE_S,  FPR32>;
233bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETO,   FCMP_SOR_S,  FPR32>;
234bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETUEQ, FCMP_SUEQ_S, FPR32>;
235bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETULT, FCMP_SULT_S, FPR32>;
236bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETULE, FCMP_SULE_S, FPR32>;
237bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETUNE, FCMP_SUNE_S, FPR32>;
238bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETUO,  FCMP_SUN_S,  FPR32>;
239bdd1243dSDimitry Andricdef : PatStrictFsetccs<SETLT,  FCMP_SLT_S,  FPR32>;
24081ad6265SDimitry Andric
24181ad6265SDimitry Andric/// Select
24281ad6265SDimitry Andric
243bdd1243dSDimitry Andricdef : Pat<(select CFR:$cc, FPR32:$fk, FPR32:$fj),
24406c3fb27SDimitry Andric          (FSEL_xS FPR32:$fj, FPR32:$fk, CFR:$cc)>;
24581ad6265SDimitry Andric
24681ad6265SDimitry Andric/// Selectcc
24781ad6265SDimitry Andric
24881ad6265SDimitry Andricclass PatFPSelectcc<CondCode cc, LAInst CmpInst, LAInst SelInst,
24981ad6265SDimitry Andric                    RegisterClass RegTy>
25081ad6265SDimitry Andric    : Pat<(select (GRLenVT (setcc RegTy:$a, RegTy:$b, cc)), RegTy:$t, RegTy:$f),
25181ad6265SDimitry Andric          (SelInst RegTy:$f, RegTy:$t, (CmpInst RegTy:$a, RegTy:$b))>;
25206c3fb27SDimitry Andricdef : PatFPSelectcc<SETOEQ, FCMP_CEQ_S,  FSEL_xS, FPR32>;
25306c3fb27SDimitry Andricdef : PatFPSelectcc<SETOLT, FCMP_CLT_S,  FSEL_xS, FPR32>;
25406c3fb27SDimitry Andricdef : PatFPSelectcc<SETOLE, FCMP_CLE_S,  FSEL_xS, FPR32>;
25506c3fb27SDimitry Andricdef : PatFPSelectcc<SETONE, FCMP_CNE_S,  FSEL_xS, FPR32>;
25606c3fb27SDimitry Andricdef : PatFPSelectcc<SETO,   FCMP_COR_S,  FSEL_xS, FPR32>;
25706c3fb27SDimitry Andricdef : PatFPSelectcc<SETUEQ, FCMP_CUEQ_S, FSEL_xS, FPR32>;
25806c3fb27SDimitry Andricdef : PatFPSelectcc<SETULT, FCMP_CULT_S, FSEL_xS, FPR32>;
25906c3fb27SDimitry Andricdef : PatFPSelectcc<SETULE, FCMP_CULE_S, FSEL_xS, FPR32>;
26006c3fb27SDimitry Andricdef : PatFPSelectcc<SETUNE, FCMP_CUNE_S, FSEL_xS, FPR32>;
26106c3fb27SDimitry Andricdef : PatFPSelectcc<SETUO,  FCMP_CUN_S,  FSEL_xS, FPR32>;
26281ad6265SDimitry Andric
263753f127fSDimitry Andric/// Loads
264753f127fSDimitry Andric
265753f127fSDimitry Andricdefm : LdPat<load, FLD_S, f32>;
266bdd1243dSDimitry Andricdef : RegRegLdPat<load, FLDX_S, f32>;
267753f127fSDimitry Andric
268753f127fSDimitry Andric/// Stores
269753f127fSDimitry Andric
270753f127fSDimitry Andricdefm : StPat<store, FST_S, FPR32, f32>;
271bdd1243dSDimitry Andricdef : RegRegStPat<store, FSTX_S, FPR32, f32>;
272753f127fSDimitry Andric
273753f127fSDimitry Andric/// Floating point constants
274753f127fSDimitry Andric
275753f127fSDimitry Andricdef : Pat<(f32 fpimm0), (MOVGR2FR_W R0)>;
276753f127fSDimitry Andricdef : Pat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W R0))>;
277753f127fSDimitry Andricdef : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>;
278753f127fSDimitry Andric
279753f127fSDimitry Andric// FP Conversion
280753f127fSDimitry Andricdef : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_W_S FPR32:$src)>;
281bdd1243dSDimitry Andric
282bdd1243dSDimitry Andric// FP reciprocal operation
283bdd1243dSDimitry Andricdef : Pat<(fdiv fpimm1, FPR32:$src), (FRECIP_S $src)>;
284bdd1243dSDimitry Andric
285*7a6dacacSDimitry Andriclet Predicates = [HasFrecipe] in {
286*7a6dacacSDimitry Andric// FP approximate reciprocal operation
287*7a6dacacSDimitry Andricdef : Pat<(int_loongarch_frecipe_s FPR32:$src), (FRECIPE_S FPR32:$src)>;
288*7a6dacacSDimitry Andricdef : Pat<(int_loongarch_frsqrte_s FPR32:$src), (FRSQRTE_S FPR32:$src)>;
289*7a6dacacSDimitry Andric}
290*7a6dacacSDimitry Andric
291bdd1243dSDimitry Andric// fmadd.s: fj * fk + fa
292bdd1243dSDimitry Andricdef : Pat<(fma FPR32:$fj, FPR32:$fk, FPR32:$fa), (FMADD_S $fj, $fk, $fa)>;
293bdd1243dSDimitry Andric
294bdd1243dSDimitry Andric// fmsub.s: fj * fk - fa
295bdd1243dSDimitry Andricdef : Pat<(fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa)),
296bdd1243dSDimitry Andric          (FMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
297bdd1243dSDimitry Andric
298bdd1243dSDimitry Andric// fnmadd.s: -(fj * fk + fa)
299bdd1243dSDimitry Andricdef : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, FPR32:$fa)),
300bdd1243dSDimitry Andric          (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
301bdd1243dSDimitry Andric
302bdd1243dSDimitry Andric// fnmadd.s: -fj * fk - fa (the nsz flag on the FMA)
303bdd1243dSDimitry Andricdef : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, (fneg FPR32:$fa)),
304bdd1243dSDimitry Andric          (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
305bdd1243dSDimitry Andric
3065f757f3fSDimitry Andric// fnmsub.s: -(fj * fk - fa)
3075f757f3fSDimitry Andricdef : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa))),
3085f757f3fSDimitry Andric          (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
3095f757f3fSDimitry Andric
3105f757f3fSDimitry Andric// fnmsub.s: -fj * fk + fa (the nsz flag on the FMA)
3115f757f3fSDimitry Andricdef : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, FPR32:$fa),
312bdd1243dSDimitry Andric          (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
31381ad6265SDimitry Andric} // Predicates = [HasBasicF]
314753f127fSDimitry Andric
315753f127fSDimitry Andriclet Predicates = [HasBasicF, IsLA64] in {
316753f127fSDimitry Andric// GPR -> FPR
317753f127fSDimitry Andricdef : Pat<(loongarch_movgr2fr_w_la64 GPR:$src), (MOVGR2FR_W GPR:$src)>;
318753f127fSDimitry Andric// FPR -> GPR
319753f127fSDimitry Andricdef : Pat<(loongarch_movfr2gr_s_la64 FPR32:$src),
320753f127fSDimitry Andric          (MOVFR2GR_S FPR32:$src)>;
321753f127fSDimitry Andric// int -> f32
322bdd1243dSDimitry Andricdef : Pat<(f32 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))),
323bdd1243dSDimitry Andric          (FFINT_S_W (MOVGR2FR_W GPR:$src))>;
324bdd1243dSDimitry Andric// uint -> f32
325bdd1243dSDimitry Andricdef : Pat<(f32 (uint_to_fp (i64 (sexti32 (i64 GPR:$src))))),
326bdd1243dSDimitry Andric          (FFINT_S_W (MOVGR2FR_W GPR:$src))>;
327bdd1243dSDimitry Andric} // Predicates = [HasBasicF, IsLA64]
328bdd1243dSDimitry Andric
329bdd1243dSDimitry Andric// FP Rounding
330bdd1243dSDimitry Andriclet Predicates = [HasBasicF, IsLA64] in {
331bdd1243dSDimitry Andricdef : PatFpr<frint, FRINT_S, FPR32>;
332753f127fSDimitry Andric} // Predicates = [HasBasicF, IsLA64]
333753f127fSDimitry Andric
334753f127fSDimitry Andriclet Predicates = [HasBasicF, IsLA32] in {
335753f127fSDimitry Andric// GPR -> FPR
336753f127fSDimitry Andricdef : Pat<(bitconvert (i32 GPR:$src)), (MOVGR2FR_W GPR:$src)>;
337753f127fSDimitry Andric// FPR -> GPR
338753f127fSDimitry Andricdef : Pat<(i32 (bitconvert FPR32:$src)), (MOVFR2GR_S FPR32:$src)>;
339753f127fSDimitry Andric// int -> f32
340753f127fSDimitry Andricdef : Pat<(f32 (sint_to_fp (i32 GPR:$src))), (FFINT_S_W (MOVGR2FR_W GPR:$src))>;
341bdd1243dSDimitry Andric} // Predicates = [HasBasicF, IsLA32]
342