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 | |