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