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 namespace LoongArchISD { 25 enum NodeType : unsigned { 26 FIRST_NUMBER = ISD::BUILTIN_OP_END, 27 28 // TODO: add more LoongArchISDs 29 CALL, 30 CALL_MEDIUM, 31 CALL_LARGE, 32 RET, 33 TAIL, 34 TAIL_MEDIUM, 35 TAIL_LARGE, 36 37 // 32-bit shifts, directly matching the semantics of the named LoongArch 38 // instructions. 39 SLL_W, 40 SRA_W, 41 SRL_W, 42 43 ROTL_W, 44 ROTR_W, 45 46 // FPR<->GPR transfer operations 47 MOVGR2FR_W_LA64, 48 MOVFR2GR_S_LA64, 49 MOVFCSR2GR, 50 MOVGR2FCSR, 51 52 FTINT, 53 54 // Bit counting operations 55 CLZ_W, 56 CTZ_W, 57 58 BSTRINS, 59 BSTRPICK, 60 61 // Byte-swapping and bit-reversal 62 REVB_2H, 63 REVB_2W, 64 BITREV_4B, 65 BITREV_W, 66 67 // Intrinsic operations start ============================================ 68 BREAK, 69 CACOP_D, 70 CACOP_W, 71 DBAR, 72 IBAR, 73 SYSCALL, 74 75 // CRC check operations 76 CRC_W_B_W, 77 CRC_W_H_W, 78 CRC_W_W_W, 79 CRC_W_D_W, 80 CRCC_W_B_W, 81 CRCC_W_H_W, 82 CRCC_W_W_W, 83 CRCC_W_D_W, 84 85 CSRRD, 86 87 // Write new value to CSR and return old value. 88 // Operand 0: A chain pointer. 89 // Operand 1: The new value to write. 90 // Operand 2: The address of the required CSR. 91 // Result 0: The old value of the CSR. 92 // Result 1: The new chain pointer. 93 CSRWR, 94 95 // Similar to CSRWR but with a write mask. 96 // Operand 0: A chain pointer. 97 // Operand 1: The new value to write. 98 // Operand 2: The write mask. 99 // Operand 3: The address of the required CSR. 100 // Result 0: The old value of the CSR. 101 // Result 1: The new chain pointer. 102 CSRXCHG, 103 104 // IOCSR access operations 105 IOCSRRD_B, 106 IOCSRRD_W, 107 IOCSRRD_H, 108 IOCSRRD_D, 109 IOCSRWR_B, 110 IOCSRWR_H, 111 IOCSRWR_W, 112 IOCSRWR_D, 113 114 // Read CPU configuration information operation 115 CPUCFG, 116 117 // Vector Shuffle 118 VREPLVE, 119 120 // Extended vector element extraction 121 VPICK_SEXT_ELT, 122 VPICK_ZEXT_ELT, 123 124 // Vector comparisons 125 VALL_ZERO, 126 VANY_ZERO, 127 VALL_NONZERO, 128 VANY_NONZERO, 129 130 // Intrinsic operations end ============================================= 131 }; 132 } // end namespace LoongArchISD 133 134 class LoongArchTargetLowering : public TargetLowering { 135 const LoongArchSubtarget &Subtarget; 136 137 public: 138 explicit LoongArchTargetLowering(const TargetMachine &TM, 139 const LoongArchSubtarget &STI); 140 141 const LoongArchSubtarget &getSubtarget() const { return Subtarget; } 142 143 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 144 145 // Provide custom lowering hooks for some operations. 146 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 147 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 148 SelectionDAG &DAG) const override; 149 150 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 151 152 // This method returns the name of a target specific DAG node. 153 const char *getTargetNodeName(unsigned Opcode) const override; 154 155 // Lower incoming arguments, copy physregs into vregs. 156 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 157 bool IsVarArg, 158 const SmallVectorImpl<ISD::InputArg> &Ins, 159 const SDLoc &DL, SelectionDAG &DAG, 160 SmallVectorImpl<SDValue> &InVals) const override; 161 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 162 bool IsVarArg, 163 const SmallVectorImpl<ISD::OutputArg> &Outs, 164 LLVMContext &Context) const override; 165 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 166 const SmallVectorImpl<ISD::OutputArg> &Outs, 167 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, 168 SelectionDAG &DAG) const override; 169 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 170 SmallVectorImpl<SDValue> &InVals) const override; 171 bool isCheapToSpeculateCttz(Type *Ty) const override; 172 bool isCheapToSpeculateCtlz(Type *Ty) const override; 173 bool hasAndNot(SDValue Y) const override; 174 TargetLowering::AtomicExpansionKind 175 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 176 177 Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, 178 Value *AlignedAddr, Value *Incr, 179 Value *Mask, Value *ShiftAmt, 180 AtomicOrdering Ord) const override; 181 182 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 183 EVT VT) const override; 184 TargetLowering::AtomicExpansionKind 185 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override; 186 Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, 187 AtomicCmpXchgInst *CI, 188 Value *AlignedAddr, Value *CmpVal, 189 Value *NewVal, Value *Mask, 190 AtomicOrdering Ord) const override; 191 192 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, 193 MachineFunction &MF, 194 unsigned Intrinsic) const override; 195 196 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, 197 EVT VT) const override; 198 199 Register 200 getExceptionPointerRegister(const Constant *PersonalityFn) const override; 201 202 Register 203 getExceptionSelectorRegister(const Constant *PersonalityFn) const override; 204 205 ISD::NodeType getExtendForAtomicOps() const override { 206 return ISD::SIGN_EXTEND; 207 } 208 209 ISD::NodeType getExtendForAtomicCmpSwapArg() const override; 210 211 Register getRegisterByName(const char *RegName, LLT VT, 212 const MachineFunction &MF) const override; 213 bool mayBeEmittedAsTailCall(const CallInst *CI) const override; 214 215 bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 216 SDValue C) const override; 217 218 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override; 219 220 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, 221 unsigned AS, 222 Instruction *I = nullptr) const override; 223 224 bool isLegalICmpImmediate(int64_t Imm) const override; 225 bool isLegalAddImmediate(int64_t Imm) const override; 226 bool isZExtFree(SDValue Val, EVT VT2) const override; 227 bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override; 228 229 bool hasAndNotCompare(SDValue Y) const override; 230 231 bool convertSelectOfConstantsToMath(EVT VT) const override { return true; } 232 233 bool allowsMisalignedMemoryAccesses( 234 EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1), 235 MachineMemOperand::Flags Flags = MachineMemOperand::MONone, 236 unsigned *Fast = nullptr) const override; 237 238 bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override { 239 return false; 240 } 241 242 private: 243 /// Target-specific function used to lower LoongArch calling conventions. 244 typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI, 245 unsigned ValNo, MVT ValVT, 246 CCValAssign::LocInfo LocInfo, 247 ISD::ArgFlagsTy ArgFlags, CCState &State, 248 bool IsFixed, bool IsReg, Type *OrigTy); 249 250 void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, 251 const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet, 252 LoongArchCCAssignFn Fn) const; 253 void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo, 254 const SmallVectorImpl<ISD::OutputArg> &Outs, 255 bool IsRet, CallLoweringInfo *CLI, 256 LoongArchCCAssignFn Fn) const; 257 258 template <class NodeTy> 259 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M, 260 bool IsLocal = true) const; 261 SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 262 unsigned Opc, bool Large = false) const; 263 SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 264 unsigned Opc, bool Large = false) const; 265 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 266 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 267 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 268 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 269 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 270 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; 271 272 MachineBasicBlock * 273 EmitInstrWithCustomInserter(MachineInstr &MI, 274 MachineBasicBlock *BB) const override; 275 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 276 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 277 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; 278 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; 279 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; 280 SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 281 SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 282 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 283 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 284 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; 285 SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; 286 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 287 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 288 SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const; 289 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 290 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 291 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 292 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; 293 294 bool isFPImmLegal(const APFloat &Imm, EVT VT, 295 bool ForCodeSize) const override; 296 297 bool shouldInsertFencesForAtomic(const Instruction *I) const override; 298 299 ConstraintType getConstraintType(StringRef Constraint) const override; 300 301 InlineAsm::ConstraintCode 302 getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 303 304 std::pair<unsigned, const TargetRegisterClass *> 305 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 306 StringRef Constraint, MVT VT) const override; 307 308 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, 309 std::vector<SDValue> &Ops, 310 SelectionDAG &DAG) const override; 311 312 bool isEligibleForTailCallOptimization( 313 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, 314 const SmallVectorImpl<CCValAssign> &ArgLocs) const; 315 }; 316 317 } // end namespace llvm 318 319 #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H 320