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 Register getRegisterByName(const char *RegName, LLT VT, 210 const MachineFunction &MF) const override; 211 bool mayBeEmittedAsTailCall(const CallInst *CI) const override; 212 213 bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 214 SDValue C) const override; 215 216 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override; 217 218 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, 219 unsigned AS, 220 Instruction *I = nullptr) const override; 221 222 bool isLegalICmpImmediate(int64_t Imm) const override; 223 bool isLegalAddImmediate(int64_t Imm) const override; 224 bool isZExtFree(SDValue Val, EVT VT2) const override; 225 bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override; 226 227 bool hasAndNotCompare(SDValue Y) const override; 228 229 bool convertSelectOfConstantsToMath(EVT VT) const override { return true; } 230 231 bool allowsMisalignedMemoryAccesses( 232 EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1), 233 MachineMemOperand::Flags Flags = MachineMemOperand::MONone, 234 unsigned *Fast = nullptr) const override; 235 236 bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override { 237 return false; 238 } 239 240 private: 241 /// Target-specific function used to lower LoongArch calling conventions. 242 typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI, 243 unsigned ValNo, MVT ValVT, 244 CCValAssign::LocInfo LocInfo, 245 ISD::ArgFlagsTy ArgFlags, CCState &State, 246 bool IsFixed, bool IsReg, Type *OrigTy); 247 248 void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, 249 const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet, 250 LoongArchCCAssignFn Fn) const; 251 void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo, 252 const SmallVectorImpl<ISD::OutputArg> &Outs, 253 bool IsRet, CallLoweringInfo *CLI, 254 LoongArchCCAssignFn Fn) const; 255 256 template <class NodeTy> 257 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M, 258 bool IsLocal = true) const; 259 SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 260 unsigned Opc, bool Large = false) const; 261 SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 262 unsigned Opc, bool Large = false) const; 263 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 264 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 265 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 266 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 267 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 268 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; 269 270 MachineBasicBlock * 271 EmitInstrWithCustomInserter(MachineInstr &MI, 272 MachineBasicBlock *BB) const override; 273 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 274 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 275 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; 276 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; 277 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; 278 SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 279 SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 280 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 281 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 282 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; 283 SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; 284 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 285 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 286 SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const; 287 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 288 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 289 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 290 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; 291 292 bool isFPImmLegal(const APFloat &Imm, EVT VT, 293 bool ForCodeSize) const override; 294 295 bool shouldInsertFencesForAtomic(const Instruction *I) const override; 296 297 ConstraintType getConstraintType(StringRef Constraint) const override; 298 299 InlineAsm::ConstraintCode 300 getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 301 302 std::pair<unsigned, const TargetRegisterClass *> 303 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 304 StringRef Constraint, MVT VT) const override; 305 306 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, 307 std::vector<SDValue> &Ops, 308 SelectionDAG &DAG) const override; 309 310 bool isEligibleForTailCallOptimization( 311 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, 312 const SmallVectorImpl<CCValAssign> &ArgLocs) const; 313 }; 314 315 } // end namespace llvm 316 317 #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H 318