LoongArchFloat32InstrInfo.td 14 KB

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