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