217 lines · c
1//===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISC-V -----===//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 defines an instruction selector for the RISC-V target.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H14#define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H15 16#include "RISCV.h"17#include "RISCVTargetMachine.h"18#include "llvm/CodeGen/SelectionDAGISel.h"19#include "llvm/Support/KnownBits.h"20 21// RISC-V specific code to select RISC-V machine instructions for22// SelectionDAG operations.23namespace llvm {24class RISCVDAGToDAGISel : public SelectionDAGISel {25 const RISCVSubtarget *Subtarget = nullptr;26 27public:28 RISCVDAGToDAGISel() = delete;29 30 explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine,31 CodeGenOptLevel OptLevel)32 : SelectionDAGISel(TargetMachine, OptLevel) {}33 34 bool runOnMachineFunction(MachineFunction &MF) override {35 Subtarget = &MF.getSubtarget<RISCVSubtarget>();36 return SelectionDAGISel::runOnMachineFunction(MF);37 }38 39 void PreprocessISelDAG() override;40 void PostprocessISelDAG() override;41 42 void Select(SDNode *Node) override;43 44 bool SelectInlineAsmMemoryOperand(const SDValue &Op,45 InlineAsm::ConstraintCode ConstraintID,46 std::vector<SDValue> &OutOps) override;47 48 bool areOffsetsWithinAlignment(SDValue Addr, Align Alignment);49 50 bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);51 bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);52 bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset);53 bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);54 55 bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,56 SDValue &Base, SDValue &Index, SDValue &Scale);57 58 template <unsigned MaxShift>59 bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index,60 SDValue &Scale) {61 return SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale);62 }63 64 bool SelectAddrRegZextRegScale(SDValue Addr, unsigned MaxShiftAmount,65 unsigned Bits, SDValue &Base, SDValue &Index,66 SDValue &Scale);67 68 template <unsigned MaxShift, unsigned Bits>69 bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index,70 SDValue &Scale) {71 return SelectAddrRegZextRegScale(Addr, MaxShift, Bits, Base, Index, Scale);72 }73 74 bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset);75 76 bool tryShrinkShlLogicImm(SDNode *Node);77 bool trySignedBitfieldExtract(SDNode *Node);78 bool trySignedBitfieldInsertInSign(SDNode *Node);79 bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT,80 SDValue X, unsigned Msb, unsigned Lsb);81 bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT,82 SDValue X, unsigned Msb, unsigned Lsb);83 bool tryIndexedLoad(SDNode *Node);84 85 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);86 bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {87 return selectShiftMask(N, Subtarget->getXLen(), ShAmt);88 }89 bool selectShiftMask32(SDValue N, SDValue &ShAmt) {90 return selectShiftMask(N, 32, ShAmt);91 }92 93 bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);94 bool selectSETNE(SDValue N, SDValue &Val) {95 return selectSETCC(N, ISD::SETNE, Val);96 }97 bool selectSETEQ(SDValue N, SDValue &Val) {98 return selectSETCC(N, ISD::SETEQ, Val);99 }100 101 bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);102 template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) {103 return selectSExtBits(N, Bits, Val);104 }105 bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val);106 template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) {107 return selectZExtBits(N, Bits, Val);108 }109 110 bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val);111 template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) {112 return selectSHXADDOp(N, ShAmt, Val);113 }114 115 bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val);116 template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) {117 return selectSHXADD_UWOp(N, ShAmt, Val);118 }119 120 bool selectZExtImm32(SDValue N, SDValue &Val);121 bool selectNegImm(SDValue N, SDValue &Val);122 bool selectInvLogicImm(SDValue N, SDValue &Val);123 124 bool orDisjoint(const SDNode *Node) const;125 bool hasAllNBitUsers(SDNode *Node, unsigned Bits,126 const unsigned Depth = 0) const;127 bool hasAllBUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 8); }128 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }129 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); }130 131 bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2);132 133 bool selectVLOp(SDValue N, SDValue &VL);134 135 bool selectVSplat(SDValue N, SDValue &SplatVal);136 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);137 bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal);138 template <unsigned Bits> bool selectVSplatUimmBits(SDValue N, SDValue &Val) {139 return selectVSplatUimm(N, Bits, Val);140 }141 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);142 bool selectVSplatSimm5Plus1NoDec(SDValue N, SDValue &SplatVal);143 bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal);144 bool selectVSplatImm64Neg(SDValue N, SDValue &SplatVal);145 // Matches the splat of a value which can be extended or truncated, such that146 // only the bottom 8 bits are preserved.147 bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal);148 bool selectScalarFPAsInt(SDValue N, SDValue &Imm);149 150 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);151 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {152 return selectRVVSimm5(N, Width, Imm);153 }154 155 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm,156 const SDLoc &DL, unsigned CurOp,157 bool IsMasked, bool IsStridedOrIndexed,158 SmallVectorImpl<SDValue> &Operands,159 bool IsLoad = false, MVT *IndexVT = nullptr);160 161 void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);162 void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked);163 void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);164 void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);165 void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);166 167 void selectVSETVLI(SDNode *Node);168 void selectXSfmmVSET(SDNode *Node);169 170 void selectSF_VC_X_SE(SDNode *Node);171 172 // Return the RISC-V condition code that matches the given DAG integer173 // condition code. The CondCode must be one of those supported by the RISC-V174 // ISA (see translateSetCCForBranch).175 static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) {176 switch (CC) {177 default:178 llvm_unreachable("Unsupported CondCode");179 case ISD::SETEQ:180 return RISCVCC::COND_EQ;181 case ISD::SETNE:182 return RISCVCC::COND_NE;183 case ISD::SETLT:184 return RISCVCC::COND_LT;185 case ISD::SETGE:186 return RISCVCC::COND_GE;187 case ISD::SETULT:188 return RISCVCC::COND_LTU;189 case ISD::SETUGE:190 return RISCVCC::COND_GEU;191 }192 }193 194// Include the pieces autogenerated from the target description.195#define GET_DAGISEL_DECL196#include "RISCVGenDAGISel.inc"197 198private:199 bool doPeepholeSExtW(SDNode *Node);200 bool doPeepholeMaskedRVV(MachineSDNode *Node);201 bool doPeepholeNoRegPassThru();202 bool performCombineVMergeAndVOps(SDNode *N);203 bool selectImm64IfCheaper(int64_t Imm, int64_t OrigImm, SDValue N,204 SDValue &Val);205};206 207class RISCVDAGToDAGISelLegacy : public SelectionDAGISelLegacy {208public:209 static char ID;210 explicit RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine,211 CodeGenOptLevel OptLevel);212};213 214} // namespace llvm215 216#endif217