| //===-- RISCVInstrInfoSFB.td - Pseudos for SFB -------------*- tablegen -*-===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file describes the pseudos for SFB (Short Forward Branch). | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | let Predicates = [HasShortForwardBranchOpt], isSelect = 1, | 
 |     Constraints = "$dst = $falsev", isCommutable = 1, Size = 8 in { | 
 | // This instruction moves $truev to $dst when the condition is true. It will | 
 | // be expanded to control flow in RISCVExpandPseudoInsts. | 
 | def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst), | 
 |                             (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                              GPR:$falsev, GPR:$truev), | 
 |                             [(set GPR:$dst, | 
 |                               (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), | 
 |                                                        GPR:$rhs, cond, | 
 |                                                        (XLenVT GPR:$truev), | 
 |                                                        GPR:$falsev))]>, | 
 |                      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                             ReadSFBALU, ReadSFBALU]>; | 
 | } | 
 |  | 
 | // This should always expand to a branch+c.mv so the size is 6 or 4 if the | 
 | // branch is compressible. | 
 | let Predicates = [HasConditionalMoveFusion, NoShortForwardBranchOpt], | 
 |     Constraints = "$dst = $falsev", isCommutable = 1, Size = 6 in { | 
 | // This instruction moves $truev to $dst when the condition is true. It will | 
 | // be expanded to control flow in RISCVExpandPseudoInsts. | 
 | // We use GPRNoX0 because c.mv cannot encode X0. | 
 | def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst), | 
 |                                 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                                  GPRNoX0:$falsev, GPRNoX0:$truev), | 
 |                                 [(set GPRNoX0:$dst, | 
 |                                   (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), | 
 |                                                            (XLenVT GPR:$rhs), | 
 |                                                            cond, (XLenVT GPRNoX0:$truev), | 
 |                                                            (XLenVT GPRNoX0:$falsev)))]>, | 
 |                          Sched<[]>; | 
 | } | 
 |  | 
 | // Conditional binops, that updates update $dst to (op rs1, rs2) when condition | 
 | // is true. Returns $falsev otherwise. Selected by optimizeSelect. | 
 | // TODO: Can we use DefaultOperands on the regular binop to accomplish this more | 
 | // like how ARM does predication? | 
 | let Predicates = [HasShortForwardBranchOpt], hasSideEffects = 0, | 
 |     mayLoad = 0, mayStore = 0, Size = 8, Constraints = "$dst = $falsev" in { | 
 | def PseudoCCADD : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSUB : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSLL : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                          ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSRL : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                          ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSRA : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                          ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCAND : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCOR  : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCXOR : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 |  | 
 | def PseudoCCADDI : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 | def PseudoCCSLLI : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 | def PseudoCCSRLI : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 | def PseudoCCSRAI : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 | def PseudoCCANDI : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 | def PseudoCCORI  : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 | def PseudoCCXORI : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU]>; | 
 |  | 
 | // RV64I instructions | 
 | def PseudoCCADDW : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                           ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSUBW : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                           ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSLLW : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSRLW : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCSRAW : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                           ReadSFBALU, ReadSFBALU]>; | 
 |  | 
 | def PseudoCCADDIW : Pseudo<(outs GPR:$dst), | 
 |                            (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                             GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                            ReadSFBALU]>; | 
 | def PseudoCCSLLIW : Pseudo<(outs GPR:$dst), | 
 |                            (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                             GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                            ReadSFBALU]>; | 
 | def PseudoCCSRLIW : Pseudo<(outs GPR:$dst), | 
 |                            (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                             GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                            ReadSFBALU]>; | 
 | def PseudoCCSRAIW : Pseudo<(outs GPR:$dst), | 
 |                            (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                             GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, | 
 |                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, | 
 |                            ReadSFBALU]>; | 
 |  | 
 | // Zbb/Zbkb instructions | 
 | def PseudoCCANDN : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                           ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCORN : Pseudo<(outs GPR:$dst), | 
 |                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | def PseudoCCXNOR : Pseudo<(outs GPR:$dst), | 
 |                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, | 
 |                            GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, | 
 |                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, | 
 |                           ReadSFBALU, ReadSFBALU, ReadSFBALU]>; | 
 | } | 
 |  | 
 | let Predicates = [HasShortForwardBranchOpt] in | 
 | def : Pat<(XLenVT (abs GPR:$rs1)), | 
 |           (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), /* COND_LT */ 2, | 
 |            (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>; | 
 | let Predicates = [HasShortForwardBranchOpt, IsRV64] in | 
 | def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32), | 
 |           (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), /* COND_LT */ 2, | 
 |            (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>; |