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