1 //===-- M68kISelLowering.h - M68k 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 /// \file 10 /// This file defines the interfaces that M68k uses to lower LLVM code into a 11 /// selection DAG. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_M68K_M68KISELLOWERING_H 16 #define LLVM_LIB_TARGET_M68K_M68KISELLOWERING_H 17 18 #include "M68k.h" 19 20 #include "llvm/CodeGen/CallingConvLower.h" 21 #include "llvm/CodeGen/SelectionDAG.h" 22 #include "llvm/CodeGen/TargetLowering.h" 23 #include "llvm/IR/Function.h" 24 25 #include <deque> 26 27 namespace llvm { 28 namespace M68kISD { 29 30 /// M68k Specific DAG nodes 31 enum NodeType { 32 /// Start the numbering from where ISD NodeType finishes. 33 FIRST_NUMBER = ISD::BUILTIN_OP_END, 34 35 CALL, 36 RET, 37 TAIL_CALL, 38 TC_RETURN, 39 40 /// M68k compare and logical compare instructions. Subtracts the source 41 /// operand from the destination data register and sets the condition 42 /// codes according to the result. Immediate always goes first. 43 CMP, 44 45 /// M68k bit-test instructions. 46 BTST, 47 48 /// M68k Select 49 SELECT, 50 51 /// M68k SetCC. Operand 0 is condition code, and operand 1 is the CCR 52 /// operand, usually produced by a CMP instruction. 53 SETCC, 54 55 // Same as SETCC except it's materialized with a subx and the value is all 56 // one's or all zero's. 57 SETCC_CARRY, // R = carry_bit ? ~0 : 0 58 59 /// M68k conditional moves. Operand 0 and operand 1 are the two values 60 /// to select from. Operand 2 is the condition code, and operand 3 is the 61 /// flag operand produced by a CMP or TEST instruction. It also writes a 62 /// flag result. 63 CMOV, 64 65 /// M68k conditional branches. Operand 0 is the chain operand, operand 1 66 /// is the block to branch if condition is true, operand 2 is the 67 /// condition code, and operand 3 is the flag operand produced by a CMP 68 /// or TEST instruction. 69 BRCOND, 70 71 // Arithmetic operations with CCR results. 72 ADD, 73 SUB, 74 ADDX, 75 SUBX, 76 SMUL, 77 UMUL, 78 OR, 79 XOR, 80 AND, 81 82 // GlobalBaseReg, 83 GLOBAL_BASE_REG, 84 85 /// A wrapper node for TargetConstantPool, 86 /// TargetExternalSymbol, and TargetGlobalAddress. 87 Wrapper, 88 89 /// Special wrapper used under M68k PIC mode for PC 90 /// relative displacements. 91 WrapperPC, 92 93 // For allocating variable amounts of stack space when using 94 // segmented stacks. Check if the current stacklet has enough space, and 95 // falls back to heap allocation if not. 96 SEG_ALLOCA, 97 }; 98 } // namespace M68kISD 99 100 /// Define some predicates that are used for node matching. 101 namespace M68k { 102 103 /// Determines whether the callee is required to pop its 104 /// own arguments. Callee pop is necessary to support tail calls. 105 bool isCalleePop(CallingConv::ID CallingConv, bool IsVarArg, bool GuaranteeTCO); 106 107 } // end namespace M68k 108 109 //===--------------------------------------------------------------------===// 110 // TargetLowering Implementation 111 //===--------------------------------------------------------------------===// 112 113 class M68kMachineFunctionInfo; 114 class M68kSubtarget; 115 116 class M68kTargetLowering : public TargetLowering { 117 const M68kSubtarget &Subtarget; 118 const M68kTargetMachine &TM; 119 120 public: 121 explicit M68kTargetLowering(const M68kTargetMachine &TM, 122 const M68kSubtarget &STI); 123 124 static const M68kTargetLowering *create(const M68kTargetMachine &TM, 125 const M68kSubtarget &STI); 126 127 const char *getTargetNodeName(unsigned Opcode) const override; 128 129 /// Return the value type to use for ISD::SETCC. 130 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 131 EVT VT) const override; 132 133 /// EVT is not used in-tree, but is used by out-of-tree target. 134 virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override; 135 136 /// Provide custom lowering hooks for some operations. 137 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 138 139 /// Return the entry encoding for a jump table in the current function. 140 /// The returned value is a member of the MachineJumpTableInfo::JTEntryKind 141 /// enum. 142 unsigned getJumpTableEncoding() const override; 143 144 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 145 const MachineBasicBlock *MBB, 146 unsigned uid, 147 MCContext &Ctx) const override; 148 149 /// Returns relocation base for the given PIC jumptable. 150 SDValue getPICJumpTableRelocBase(SDValue Table, 151 SelectionDAG &DAG) const override; 152 153 /// This returns the relocation base for the given PIC jumptable, 154 /// the same as getPICJumpTableRelocBase, but as an MCExpr. 155 const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF, 156 unsigned JTI, 157 MCContext &Ctx) const override; 158 159 ConstraintType getConstraintType(StringRef ConstraintStr) const override; 160 161 std::pair<unsigned, const TargetRegisterClass *> 162 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 163 StringRef Constraint, MVT VT) const override; 164 165 // Lower operand with C_Immediate and C_Other constraint type 166 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, 167 std::vector<SDValue> &Ops, 168 SelectionDAG &DAG) const override; 169 170 MachineBasicBlock * 171 EmitInstrWithCustomInserter(MachineInstr &MI, 172 MachineBasicBlock *MBB) const override; 173 174 CCAssignFn *getCCAssignFn(CallingConv::ID CC, bool Return, 175 bool IsVarArg) const; 176 177 AtomicExpansionKind 178 shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override; 179 180 /// If a physical register, this returns the register that receives the 181 /// exception address on entry to an EH pad. 182 Register 183 getExceptionPointerRegister(const Constant *PersonalityFn) const override; 184 185 /// If a physical register, this returns the register that receives the 186 /// exception typeid on entry to a landing pad. 187 Register 188 getExceptionSelectorRegister(const Constant *PersonalityFn) const override; 189 190 InlineAsm::ConstraintCode 191 getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 192 193 private: 194 unsigned GetAlignedArgumentStackSize(unsigned StackSize, 195 SelectionDAG &DAG) const; 196 197 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override { 198 // In many cases, `GA` doesn't give the correct offset to fold. It's 199 // hard to know if the real offset actually fits into the displacement 200 // of the perspective addressing mode. 201 // Thus, we disable offset folding altogether and leave that to ISel 202 // patterns. 203 return false; 204 } 205 206 SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; 207 208 /// Emit a load of return address if tail call 209 /// optimization is performed and it is required. 210 SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr, 211 SDValue Chain, bool IsTailCall, int FPDiff, 212 const SDLoc &DL) const; 213 214 /// Emit a store of the return address if tail call 215 /// optimization is performed and it is required (FPDiff!=0). 216 SDValue EmitTailCallStoreRetAddr(SelectionDAG &DAG, MachineFunction &MF, 217 SDValue Chain, SDValue RetAddrFrIdx, 218 EVT PtrVT, unsigned SlotSize, int FPDiff, 219 const SDLoc &DL) const; 220 221 SDValue LowerMemArgument(SDValue Chain, CallingConv::ID CallConv, 222 const SmallVectorImpl<ISD::InputArg> &ArgInfo, 223 const SDLoc &DL, SelectionDAG &DAG, 224 const CCValAssign &VA, MachineFrameInfo &MFI, 225 unsigned ArgIdx) const; 226 227 SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg, 228 const SDLoc &DL, SelectionDAG &DAG, 229 const CCValAssign &VA, ISD::ArgFlagsTy Flags) const; 230 231 SDValue LowerXALUO(SDValue Op, SelectionDAG &DAG) const; 232 SDValue LowerToBTST(SDValue And, ISD::CondCode CC, const SDLoc &DL, 233 SelectionDAG &DAG) const; 234 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 235 SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const; 236 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; 237 SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; 238 SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) const; 239 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 240 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 241 SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; 242 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 243 SDValue LowerGlobalAddress(const GlobalValue *GV, const SDLoc &DL, 244 int64_t Offset, SelectionDAG &DAG) const; 245 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 246 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 247 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 248 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 249 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; 250 251 SDValue LowerATOMICFENCE(SDValue Op, SelectionDAG &DAG) const; 252 253 SDValue LowerCallResult(SDValue Chain, SDValue InGlue, 254 CallingConv::ID CallConv, bool IsVarArg, 255 const SmallVectorImpl<ISD::InputArg> &Ins, 256 const SDLoc &DL, SelectionDAG &DAG, 257 SmallVectorImpl<SDValue> &InVals) const; 258 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 259 260 /// LowerFormalArguments - transform physical registers into virtual 261 /// registers and generate load operations for arguments places on the stack. 262 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CCID, 263 bool IsVarArg, 264 const SmallVectorImpl<ISD::InputArg> &Ins, 265 const SDLoc &DL, SelectionDAG &DAG, 266 SmallVectorImpl<SDValue> &InVals) const override; 267 268 SDValue LowerCall(CallLoweringInfo &CLI, 269 SmallVectorImpl<SDValue> &InVals) const override; 270 271 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 272 bool isVarArg, 273 const SmallVectorImpl<ISD::OutputArg> &Outs, 274 LLVMContext &Context) const override; 275 276 /// Lower the result values of a call into the 277 /// appropriate copies out of appropriate physical registers. 278 SDValue LowerReturn(SDValue Chain, CallingConv::ID CCID, bool IsVarArg, 279 const SmallVectorImpl<ISD::OutputArg> &Outs, 280 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, 281 SelectionDAG &DAG) const override; 282 283 SDValue LowerExternalSymbolCall(SelectionDAG &DAG, SDLoc loc, 284 llvm::StringRef SymbolName, 285 ArgListTy &&ArgList) const; 286 SDValue getTLSGetAddr(GlobalAddressSDNode *GA, SelectionDAG &DAG, 287 unsigned TargetFlags) const; 288 SDValue getM68kReadTp(SDLoc Loc, SelectionDAG &DAG) const; 289 290 SDValue LowerTLSGeneralDynamic(GlobalAddressSDNode *GA, 291 SelectionDAG &DAG) const; 292 SDValue LowerTLSLocalDynamic(GlobalAddressSDNode *GA, 293 SelectionDAG &DAG) const; 294 SDValue LowerTLSInitialExec(GlobalAddressSDNode *GA, SelectionDAG &DAG) const; 295 SDValue LowerTLSLocalExec(GlobalAddressSDNode *GA, SelectionDAG &DAG) const; 296 297 bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 298 SDValue C) const override; 299 300 MachineBasicBlock *EmitLoweredSelect(MachineInstr &I, 301 MachineBasicBlock *MBB) const; 302 MachineBasicBlock *EmitLoweredSegAlloca(MachineInstr &MI, 303 MachineBasicBlock *BB) const; 304 305 /// Emit nodes that will be selected as "test Op0,Op0", or something 306 /// equivalent, for use with the given M68k condition code. 307 SDValue EmitTest(SDValue Op0, unsigned M68kCC, const SDLoc &dl, 308 SelectionDAG &DAG) const; 309 310 /// Emit nodes that will be selected as "cmp Op0,Op1", or something 311 /// equivalent, for use with the given M68k condition code. 312 SDValue EmitCmp(SDValue Op0, SDValue Op1, unsigned M68kCC, const SDLoc &dl, 313 SelectionDAG &DAG) const; 314 315 /// Check whether the call is eligible for tail call optimization. Targets 316 /// that want to do tail call optimization should implement this function. 317 bool IsEligibleForTailCallOptimization( 318 SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg, 319 bool IsCalleeStructRet, bool IsCallerStructRet, Type *RetTy, 320 const SmallVectorImpl<ISD::OutputArg> &Outs, 321 const SmallVectorImpl<SDValue> &OutVals, 322 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const; 323 324 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 325 }; 326 } // namespace llvm 327 328 #endif // LLVM_LIB_TARGET_M68K_M68KISELLOWERING_H 329