1 //=- LoongArchISelLowering.h - LoongArch DAG Lowering Interface -*- C++ -*-===// 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 defines the interfaces that LoongArch uses to lower LLVM code into 10 // a selection DAG. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H 15 #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H 16 17 #include "LoongArch.h" 18 #include "llvm/CodeGen/CallingConvLower.h" 19 #include "llvm/CodeGen/SelectionDAG.h" 20 #include "llvm/CodeGen/TargetLowering.h" 21 22 namespace llvm { 23 class LoongArchSubtarget; 24 struct LoongArchRegisterInfo; 25 namespace LoongArchISD { 26 enum NodeType : unsigned { 27 FIRST_NUMBER = ISD::BUILTIN_OP_END, 28 29 // TODO: add more LoongArchISDs 30 CALL, 31 RET, 32 TAIL, 33 34 // 32-bit shifts, directly matching the semantics of the named LoongArch 35 // instructions. 36 SLL_W, 37 SRA_W, 38 SRL_W, 39 40 ROTL_W, 41 ROTR_W, 42 43 // FPR<->GPR transfer operations 44 MOVGR2FR_W_LA64, 45 MOVFR2GR_S_LA64, 46 MOVFCSR2GR, 47 MOVGR2FCSR, 48 49 FTINT, 50 51 // Bit counting operations 52 CLZ_W, 53 CTZ_W, 54 55 BSTRINS, 56 BSTRPICK, 57 58 // Byte-swapping and bit-reversal 59 REVB_2H, 60 REVB_2W, 61 BITREV_4B, 62 BITREV_W, 63 64 // Intrinsic operations start ============================================ 65 BREAK, 66 CACOP_D, 67 CACOP_W, 68 DBAR, 69 IBAR, 70 SYSCALL, 71 72 // CRC check operations 73 CRC_W_B_W, 74 CRC_W_H_W, 75 CRC_W_W_W, 76 CRC_W_D_W, 77 CRCC_W_B_W, 78 CRCC_W_H_W, 79 CRCC_W_W_W, 80 CRCC_W_D_W, 81 82 CSRRD, 83 CSRWR, 84 CSRXCHG, 85 86 // IOCSR access operations 87 IOCSRRD_B, 88 IOCSRRD_W, 89 IOCSRRD_H, 90 IOCSRRD_D, 91 IOCSRWR_B, 92 IOCSRWR_H, 93 IOCSRWR_W, 94 IOCSRWR_D, 95 96 // Read CPU configuration information operation 97 CPUCFG, 98 // Intrinsic operations end ============================================= 99 }; 100 } // end namespace LoongArchISD 101 102 class LoongArchTargetLowering : public TargetLowering { 103 const LoongArchSubtarget &Subtarget; 104 105 public: 106 explicit LoongArchTargetLowering(const TargetMachine &TM, 107 const LoongArchSubtarget &STI); 108 109 const LoongArchSubtarget &getSubtarget() const { return Subtarget; } 110 111 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 112 113 // Provide custom lowering hooks for some operations. 114 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 115 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 116 SelectionDAG &DAG) const override; 117 118 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 119 120 // This method returns the name of a target specific DAG node. 121 const char *getTargetNodeName(unsigned Opcode) const override; 122 123 // Lower incoming arguments, copy physregs into vregs. 124 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 125 bool IsVarArg, 126 const SmallVectorImpl<ISD::InputArg> &Ins, 127 const SDLoc &DL, SelectionDAG &DAG, 128 SmallVectorImpl<SDValue> &InVals) const override; 129 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 130 bool IsVarArg, 131 const SmallVectorImpl<ISD::OutputArg> &Outs, 132 LLVMContext &Context) const override; 133 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 134 const SmallVectorImpl<ISD::OutputArg> &Outs, 135 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, 136 SelectionDAG &DAG) const override; 137 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 138 SmallVectorImpl<SDValue> &InVals) const override; 139 bool isCheapToSpeculateCttz(Type *Ty) const override; 140 bool isCheapToSpeculateCtlz(Type *Ty) const override; 141 bool hasAndNot(SDValue Y) const override; 142 TargetLowering::AtomicExpansionKind 143 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 144 145 Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, 146 Value *AlignedAddr, Value *Incr, 147 Value *Mask, Value *ShiftAmt, 148 AtomicOrdering Ord) const override; 149 150 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 151 EVT VT) const override; 152 TargetLowering::AtomicExpansionKind 153 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override; 154 Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, 155 AtomicCmpXchgInst *CI, 156 Value *AlignedAddr, Value *CmpVal, 157 Value *NewVal, Value *Mask, 158 AtomicOrdering Ord) const override; 159 160 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, 161 MachineFunction &MF, 162 unsigned Intrinsic) const override; 163 164 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, 165 EVT VT) const override; 166 167 Register 168 getExceptionPointerRegister(const Constant *PersonalityFn) const override; 169 170 Register 171 getExceptionSelectorRegister(const Constant *PersonalityFn) const override; 172 173 ISD::NodeType getExtendForAtomicOps() const override { 174 return ISD::SIGN_EXTEND; 175 } 176 177 Register getRegisterByName(const char *RegName, LLT VT, 178 const MachineFunction &MF) const override; 179 bool mayBeEmittedAsTailCall(const CallInst *CI) const override; 180 181 bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 182 SDValue C) const override; 183 184 private: 185 /// Target-specific function used to lower LoongArch calling conventions. 186 typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI, 187 unsigned ValNo, MVT ValVT, 188 CCValAssign::LocInfo LocInfo, 189 ISD::ArgFlagsTy ArgFlags, CCState &State, 190 bool IsFixed, bool IsReg, Type *OrigTy); 191 192 void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, 193 const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet, 194 LoongArchCCAssignFn Fn) const; 195 void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo, 196 const SmallVectorImpl<ISD::OutputArg> &Outs, 197 bool IsRet, CallLoweringInfo *CLI, 198 LoongArchCCAssignFn Fn) const; 199 200 template <class NodeTy> 201 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const; 202 SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 203 unsigned Opc) const; 204 SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 205 unsigned Opc) const; 206 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 207 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 208 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 209 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 210 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 211 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; 212 213 MachineBasicBlock * 214 EmitInstrWithCustomInserter(MachineInstr &MI, 215 MachineBasicBlock *BB) const override; 216 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 217 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; 218 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; 219 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; 220 SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 221 SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 222 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 223 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 224 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; 225 SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; 226 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 227 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 228 SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const; 229 230 bool isFPImmLegal(const APFloat &Imm, EVT VT, 231 bool ForCodeSize) const override; 232 233 bool shouldInsertFencesForAtomic(const Instruction *I) const override; 234 235 ConstraintType getConstraintType(StringRef Constraint) const override; 236 237 unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 238 239 std::pair<unsigned, const TargetRegisterClass *> 240 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 241 StringRef Constraint, MVT VT) const override; 242 243 void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 244 std::vector<SDValue> &Ops, 245 SelectionDAG &DAG) const override; 246 247 bool isEligibleForTailCallOptimization( 248 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, 249 const SmallVectorImpl<CCValAssign> &ArgLocs) const; 250 }; 251 252 } // end namespace llvm 253 254 #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H 255