Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
35269 views
//===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISC-V -----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines an instruction selector for the RISC-V target.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H13#define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H1415#include "RISCV.h"16#include "RISCVTargetMachine.h"17#include "llvm/CodeGen/SelectionDAGISel.h"18#include "llvm/Support/KnownBits.h"1920// RISC-V specific code to select RISC-V machine instructions for21// SelectionDAG operations.22namespace llvm {23class RISCVDAGToDAGISel : public SelectionDAGISel {24const RISCVSubtarget *Subtarget = nullptr;2526public:27RISCVDAGToDAGISel() = delete;2829explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine,30CodeGenOptLevel OptLevel)31: SelectionDAGISel(TargetMachine, OptLevel) {}3233bool runOnMachineFunction(MachineFunction &MF) override {34Subtarget = &MF.getSubtarget<RISCVSubtarget>();35return SelectionDAGISel::runOnMachineFunction(MF);36}3738void PreprocessISelDAG() override;39void PostprocessISelDAG() override;4041void Select(SDNode *Node) override;4243bool SelectInlineAsmMemoryOperand(const SDValue &Op,44InlineAsm::ConstraintCode ConstraintID,45std::vector<SDValue> &OutOps) override;4647bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);48bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);49bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset,50bool IsINX = false);51bool SelectAddrRegImmINX(SDValue Addr, SDValue &Base, SDValue &Offset) {52return SelectAddrRegImm(Addr, Base, Offset, true);53}54bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);5556bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,57SDValue &Base, SDValue &Index, SDValue &Scale);5859template <unsigned MaxShift>60bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index,61SDValue &Scale) {62return SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale);63}6465template <unsigned MaxShift, unsigned Bits>66bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index,67SDValue &Scale) {68if (SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale)) {69if (Index.getOpcode() == ISD::AND) {70auto *C = dyn_cast<ConstantSDNode>(Index.getOperand(1));71if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) {72Index = Index.getOperand(0);73return true;74}75}76}77return false;78}7980bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset);8182bool tryShrinkShlLogicImm(SDNode *Node);83bool trySignedBitfieldExtract(SDNode *Node);84bool tryIndexedLoad(SDNode *Node);8586bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);87bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {88return selectShiftMask(N, Subtarget->getXLen(), ShAmt);89}90bool selectShiftMask32(SDValue N, SDValue &ShAmt) {91return selectShiftMask(N, 32, ShAmt);92}9394bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);95bool selectSETNE(SDValue N, SDValue &Val) {96return selectSETCC(N, ISD::SETNE, Val);97}98bool selectSETEQ(SDValue N, SDValue &Val) {99return selectSETCC(N, ISD::SETEQ, Val);100}101102bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);103template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) {104return selectSExtBits(N, Bits, Val);105}106bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val);107template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) {108return selectZExtBits(N, Bits, Val);109}110111bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val);112template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) {113return selectSHXADDOp(N, ShAmt, Val);114}115116bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val);117template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) {118return selectSHXADD_UWOp(N, ShAmt, Val);119}120121bool hasAllNBitUsers(SDNode *Node, unsigned Bits,122const unsigned Depth = 0) const;123bool hasAllBUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 8); }124bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }125bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); }126127bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2);128129bool selectVLOp(SDValue N, SDValue &VL);130131bool selectVSplat(SDValue N, SDValue &SplatVal);132bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);133bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal);134template <unsigned Bits> bool selectVSplatUimmBits(SDValue N, SDValue &Val) {135return selectVSplatUimm(N, Bits, Val);136}137bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);138bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal);139// Matches the splat of a value which can be extended or truncated, such that140// only the bottom 8 bits are preserved.141bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal);142bool selectFPImm(SDValue N, SDValue &Imm);143144bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);145template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {146return selectRVVSimm5(N, Width, Imm);147}148149void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm,150const SDLoc &DL, unsigned CurOp,151bool IsMasked, bool IsStridedOrIndexed,152SmallVectorImpl<SDValue> &Operands,153bool IsLoad = false, MVT *IndexVT = nullptr);154155void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided);156void selectVLSEGFF(SDNode *Node, bool IsMasked);157void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);158void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided);159void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);160161void selectVSETVLI(SDNode *Node);162163void selectSF_VC_X_SE(SDNode *Node);164165// Return the RISC-V condition code that matches the given DAG integer166// condition code. The CondCode must be one of those supported by the RISC-V167// ISA (see translateSetCCForBranch).168static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) {169switch (CC) {170default:171llvm_unreachable("Unsupported CondCode");172case ISD::SETEQ:173return RISCVCC::COND_EQ;174case ISD::SETNE:175return RISCVCC::COND_NE;176case ISD::SETLT:177return RISCVCC::COND_LT;178case ISD::SETGE:179return RISCVCC::COND_GE;180case ISD::SETULT:181return RISCVCC::COND_LTU;182case ISD::SETUGE:183return RISCVCC::COND_GEU;184}185}186187// Include the pieces autogenerated from the target description.188#include "RISCVGenDAGISel.inc"189190private:191bool doPeepholeSExtW(SDNode *Node);192bool doPeepholeMaskedRVV(MachineSDNode *Node);193bool doPeepholeMergeVVMFold();194bool doPeepholeNoRegPassThru();195bool performCombineVMergeAndVOps(SDNode *N);196};197198class RISCVDAGToDAGISelLegacy : public SelectionDAGISelLegacy {199public:200static char ID;201explicit RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine,202CodeGenOptLevel OptLevel);203};204205namespace RISCV {206struct VLSEGPseudo {207uint16_t NF : 4;208uint16_t Masked : 1;209uint16_t Strided : 1;210uint16_t FF : 1;211uint16_t Log2SEW : 3;212uint16_t LMUL : 3;213uint16_t Pseudo;214};215216struct VLXSEGPseudo {217uint16_t NF : 4;218uint16_t Masked : 1;219uint16_t Ordered : 1;220uint16_t Log2SEW : 3;221uint16_t LMUL : 3;222uint16_t IndexLMUL : 3;223uint16_t Pseudo;224};225226struct VSSEGPseudo {227uint16_t NF : 4;228uint16_t Masked : 1;229uint16_t Strided : 1;230uint16_t Log2SEW : 3;231uint16_t LMUL : 3;232uint16_t Pseudo;233};234235struct VSXSEGPseudo {236uint16_t NF : 4;237uint16_t Masked : 1;238uint16_t Ordered : 1;239uint16_t Log2SEW : 3;240uint16_t LMUL : 3;241uint16_t IndexLMUL : 3;242uint16_t Pseudo;243};244245struct VLEPseudo {246uint16_t Masked : 1;247uint16_t Strided : 1;248uint16_t FF : 1;249uint16_t Log2SEW : 3;250uint16_t LMUL : 3;251uint16_t Pseudo;252};253254struct VSEPseudo {255uint16_t Masked :1;256uint16_t Strided : 1;257uint16_t Log2SEW : 3;258uint16_t LMUL : 3;259uint16_t Pseudo;260};261262struct VLX_VSXPseudo {263uint16_t Masked : 1;264uint16_t Ordered : 1;265uint16_t Log2SEW : 3;266uint16_t LMUL : 3;267uint16_t IndexLMUL : 3;268uint16_t Pseudo;269};270271#define GET_RISCVVSSEGTable_DECL272#define GET_RISCVVLSEGTable_DECL273#define GET_RISCVVLXSEGTable_DECL274#define GET_RISCVVSXSEGTable_DECL275#define GET_RISCVVLETable_DECL276#define GET_RISCVVSETable_DECL277#define GET_RISCVVLXTable_DECL278#define GET_RISCVVSXTable_DECL279} // namespace RISCV280281} // namespace llvm282283#endif284285286