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