Path: blob/main/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
35269 views
//=- LoongArchISelLowering.h - LoongArch DAG Lowering Interface -*- C++ -*-===//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 the interfaces that LoongArch uses to lower LLVM code into9// a selection DAG.10//11//===----------------------------------------------------------------------===//1213#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H14#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H1516#include "LoongArch.h"17#include "llvm/CodeGen/CallingConvLower.h"18#include "llvm/CodeGen/SelectionDAG.h"19#include "llvm/CodeGen/TargetLowering.h"2021namespace llvm {22class LoongArchSubtarget;23namespace LoongArchISD {24enum NodeType : unsigned {25FIRST_NUMBER = ISD::BUILTIN_OP_END,2627// TODO: add more LoongArchISDs28CALL,29CALL_MEDIUM,30CALL_LARGE,31RET,32TAIL,33TAIL_MEDIUM,34TAIL_LARGE,3536// 32-bit shifts, directly matching the semantics of the named LoongArch37// instructions.38SLL_W,39SRA_W,40SRL_W,4142ROTL_W,43ROTR_W,4445// unsigned 32-bit integer division46DIV_WU,47MOD_WU,4849// FPR<->GPR transfer operations50MOVGR2FR_W_LA64,51MOVFR2GR_S_LA64,52MOVFCSR2GR,53MOVGR2FCSR,5455FTINT,5657// Bit counting operations58CLZ_W,59CTZ_W,6061BSTRINS,62BSTRPICK,6364// Byte-swapping and bit-reversal65REVB_2H,66REVB_2W,67BITREV_4B,68BITREV_W,6970// Intrinsic operations start ============================================71BREAK,72CACOP_D,73CACOP_W,74DBAR,75IBAR,76SYSCALL,7778// CRC check operations79CRC_W_B_W,80CRC_W_H_W,81CRC_W_W_W,82CRC_W_D_W,83CRCC_W_B_W,84CRCC_W_H_W,85CRCC_W_W_W,86CRCC_W_D_W,8788CSRRD,8990// Write new value to CSR and return old value.91// Operand 0: A chain pointer.92// Operand 1: The new value to write.93// Operand 2: The address of the required CSR.94// Result 0: The old value of the CSR.95// Result 1: The new chain pointer.96CSRWR,9798// Similar to CSRWR but with a write mask.99// Operand 0: A chain pointer.100// Operand 1: The new value to write.101// Operand 2: The write mask.102// Operand 3: The address of the required CSR.103// Result 0: The old value of the CSR.104// Result 1: The new chain pointer.105CSRXCHG,106107// IOCSR access operations108IOCSRRD_B,109IOCSRRD_W,110IOCSRRD_H,111IOCSRRD_D,112IOCSRWR_B,113IOCSRWR_H,114IOCSRWR_W,115IOCSRWR_D,116117// Read CPU configuration information operation118CPUCFG,119120// Vector Shuffle121VREPLVE,122VSHUF,123VPICKEV,124VPICKOD,125VPACKEV,126VPACKOD,127VILVL,128VILVH,129VSHUF4I,130VREPLVEI,131XVPERMI,132133// Extended vector element extraction134VPICK_SEXT_ELT,135VPICK_ZEXT_ELT,136137// Vector comparisons138VALL_ZERO,139VANY_ZERO,140VALL_NONZERO,141VANY_NONZERO,142143// Intrinsic operations end =============================================144};145} // end namespace LoongArchISD146147class LoongArchTargetLowering : public TargetLowering {148const LoongArchSubtarget &Subtarget;149150public:151explicit LoongArchTargetLowering(const TargetMachine &TM,152const LoongArchSubtarget &STI);153154const LoongArchSubtarget &getSubtarget() const { return Subtarget; }155156bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;157158// Provide custom lowering hooks for some operations.159SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;160void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,161SelectionDAG &DAG) const override;162163SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;164165// This method returns the name of a target specific DAG node.166const char *getTargetNodeName(unsigned Opcode) const override;167168// Lower incoming arguments, copy physregs into vregs.169SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,170bool IsVarArg,171const SmallVectorImpl<ISD::InputArg> &Ins,172const SDLoc &DL, SelectionDAG &DAG,173SmallVectorImpl<SDValue> &InVals) const override;174bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,175bool IsVarArg,176const SmallVectorImpl<ISD::OutputArg> &Outs,177LLVMContext &Context) const override;178SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,179const SmallVectorImpl<ISD::OutputArg> &Outs,180const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,181SelectionDAG &DAG) const override;182SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,183SmallVectorImpl<SDValue> &InVals) const override;184bool isCheapToSpeculateCttz(Type *Ty) const override;185bool isCheapToSpeculateCtlz(Type *Ty) const override;186bool hasAndNot(SDValue Y) const override;187TargetLowering::AtomicExpansionKind188shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;189190Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,191Value *AlignedAddr, Value *Incr,192Value *Mask, Value *ShiftAmt,193AtomicOrdering Ord) const override;194195EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,196EVT VT) const override;197TargetLowering::AtomicExpansionKind198shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override;199Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,200AtomicCmpXchgInst *CI,201Value *AlignedAddr, Value *CmpVal,202Value *NewVal, Value *Mask,203AtomicOrdering Ord) const override;204205bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,206MachineFunction &MF,207unsigned Intrinsic) const override;208209bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,210EVT VT) const override;211212Register213getExceptionPointerRegister(const Constant *PersonalityFn) const override;214215Register216getExceptionSelectorRegister(const Constant *PersonalityFn) const override;217218ISD::NodeType getExtendForAtomicOps() const override {219return ISD::SIGN_EXTEND;220}221222ISD::NodeType getExtendForAtomicCmpSwapArg() const override;223224Register getRegisterByName(const char *RegName, LLT VT,225const MachineFunction &MF) const override;226bool mayBeEmittedAsTailCall(const CallInst *CI) const override;227228bool decomposeMulByConstant(LLVMContext &Context, EVT VT,229SDValue C) const override;230231bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;232233bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,234unsigned AS,235Instruction *I = nullptr) const override;236237bool isLegalICmpImmediate(int64_t Imm) const override;238bool isLegalAddImmediate(int64_t Imm) const override;239bool isZExtFree(SDValue Val, EVT VT2) const override;240bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;241bool signExtendConstant(const ConstantInt *CI) const override;242243bool hasAndNotCompare(SDValue Y) const override;244245bool convertSelectOfConstantsToMath(EVT VT) const override { return true; }246247bool allowsMisalignedMemoryAccesses(248EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1),249MachineMemOperand::Flags Flags = MachineMemOperand::MONone,250unsigned *Fast = nullptr) const override;251252bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override {253return false;254}255bool shouldConsiderGEPOffsetSplit() const override { return true; }256bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override;257bool shouldExtendTypeInLibCall(EVT Type) const override;258259private:260/// Target-specific function used to lower LoongArch calling conventions.261typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,262unsigned ValNo, MVT ValVT,263CCValAssign::LocInfo LocInfo,264ISD::ArgFlagsTy ArgFlags, CCState &State,265bool IsFixed, bool IsReg, Type *OrigTy);266267void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,268const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,269LoongArchCCAssignFn Fn) const;270void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,271const SmallVectorImpl<ISD::OutputArg> &Outs,272bool IsRet, CallLoweringInfo *CLI,273LoongArchCCAssignFn Fn) const;274275template <class NodeTy>276SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,277bool IsLocal = true) const;278SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,279unsigned Opc, bool UseGOT, bool Large = false) const;280SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,281unsigned Opc, bool Large = false) const;282SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,283unsigned Opc, bool Large = false) const;284SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;285SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;286SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;287SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;288SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;289SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;290291MachineBasicBlock *292EmitInstrWithCustomInserter(MachineInstr &MI,293MachineBasicBlock *BB) const override;294SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;295SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;296SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;297SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;298SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;299SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;300SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;301SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;302SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;303SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;304SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;305SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;306SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;307SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const;308SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;309SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;310SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;311SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;312313bool isFPImmLegal(const APFloat &Imm, EVT VT,314bool ForCodeSize) const override;315316bool shouldInsertFencesForAtomic(const Instruction *I) const override;317318ConstraintType getConstraintType(StringRef Constraint) const override;319320InlineAsm::ConstraintCode321getInlineAsmMemConstraint(StringRef ConstraintCode) const override;322323std::pair<unsigned, const TargetRegisterClass *>324getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,325StringRef Constraint, MVT VT) const override;326327void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,328std::vector<SDValue> &Ops,329SelectionDAG &DAG) const override;330331bool isEligibleForTailCallOptimization(332CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,333const SmallVectorImpl<CCValAssign> &ArgLocs) const;334};335336} // end namespace llvm337338#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H339340341