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