1249259Sdim//==-- AArch64ISelLowering.h - AArch64 DAG Lowering Interface ----*- C++ -*-==//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// This file defines the interfaces that AArch64 uses to lower LLVM code into a
11249259Sdim// selection DAG.
12249259Sdim//
13249259Sdim//===----------------------------------------------------------------------===//
14249259Sdim
15249259Sdim#ifndef LLVM_TARGET_AARCH64_ISELLOWERING_H
16249259Sdim#define LLVM_TARGET_AARCH64_ISELLOWERING_H
17249259Sdim
18249259Sdim#include "Utils/AArch64BaseInfo.h"
19249259Sdim#include "llvm/CodeGen/CallingConvLower.h"
20249259Sdim#include "llvm/CodeGen/SelectionDAG.h"
21249259Sdim#include "llvm/Target/TargetLowering.h"
22263508Sdim#include "llvm/IR/Intrinsics.h"
23249259Sdim
24249259Sdimnamespace llvm {
25249259Sdimnamespace AArch64ISD {
26249259Sdim  enum NodeType {
27249259Sdim    // Start the numbering from where ISD NodeType finishes.
28249259Sdim    FIRST_NUMBER = ISD::BUILTIN_OP_END,
29249259Sdim
30249259Sdim    // This is a conditional branch which also notes the flag needed
31249259Sdim    // (eq/sgt/...). A64 puts this information on the branches rather than
32249259Sdim    // compares as LLVM does.
33249259Sdim    BR_CC,
34249259Sdim
35249259Sdim    // A node to be selected to an actual call operation: either BL or BLR in
36249259Sdim    // the absence of tail calls.
37249259Sdim    Call,
38249259Sdim
39249259Sdim    // Indicates a floating-point immediate which fits into the format required
40249259Sdim    // by the FMOV instructions. First (and only) operand is the 8-bit encoded
41249259Sdim    // value of that immediate.
42249259Sdim    FPMOV,
43249259Sdim
44249259Sdim    // Corresponds directly to an EXTR instruction. Operands are an LHS an RHS
45249259Sdim    // and an LSB.
46249259Sdim    EXTR,
47249259Sdim
48249259Sdim    // Wraps a load from the GOT, which should always be performed with a 64-bit
49249259Sdim    // load instruction. This prevents the DAG combiner folding a truncate to
50249259Sdim    // form a smaller memory access.
51249259Sdim    GOTLoad,
52249259Sdim
53249259Sdim    // Performs a bitfield insert. Arguments are: the value being inserted into;
54249259Sdim    // the value being inserted; least significant bit changed; width of the
55249259Sdim    // field.
56249259Sdim    BFI,
57249259Sdim
58249259Sdim    // Simply a convenient node inserted during ISelLowering to represent
59249259Sdim    // procedure return. Will almost certainly be selected to "RET".
60249259Sdim    Ret,
61249259Sdim
62249259Sdim    /// Extracts a field of contiguous bits from the source and sign extends
63249259Sdim    /// them into a single register. Arguments are: source; immr; imms. Note
64249259Sdim    /// these are pre-encoded since DAG matching can't cope with combining LSB
65249259Sdim    /// and Width into these values itself.
66249259Sdim    SBFX,
67249259Sdim
68249259Sdim    /// This is an A64-ification of the standard LLVM SELECT_CC operation. The
69249259Sdim    /// main difference is that it only has the values and an A64 condition,
70249259Sdim    /// which will be produced by a setcc instruction.
71249259Sdim    SELECT_CC,
72249259Sdim
73249259Sdim    /// This serves most of the functions of the LLVM SETCC instruction, for two
74249259Sdim    /// purposes. First, it prevents optimisations from fiddling with the
75249259Sdim    /// compare after we've moved the CondCode information onto the SELECT_CC or
76249259Sdim    /// BR_CC instructions. Second, it gives a legal instruction for the actual
77249259Sdim    /// comparison.
78249259Sdim    ///
79249259Sdim    /// It keeps a record of the condition flags asked for because certain
80249259Sdim    /// instructions are only valid for a subset of condition codes.
81249259Sdim    SETCC,
82249259Sdim
83249259Sdim    // Designates a node which is a tail call: both a call and a return
84249259Sdim    // instruction as far as selction is concerned. It should be selected to an
85249259Sdim    // unconditional branch. Has the usual plethora of call operands, but: 1st
86249259Sdim    // is callee, 2nd is stack adjustment required immediately before branch.
87249259Sdim    TC_RETURN,
88249259Sdim
89249259Sdim    // Designates a call used to support the TLS descriptor ABI. The call itself
90249259Sdim    // will be indirect ("BLR xN") but a relocation-specifier (".tlsdesccall
91249259Sdim    // var") must be attached somehow during code generation. It takes two
92249259Sdim    // operands: the callee and the symbol to be relocated against.
93249259Sdim    TLSDESCCALL,
94249259Sdim
95249259Sdim    // Leaf node which will be lowered to an appropriate MRS to obtain the
96249259Sdim    // thread pointer: TPIDR_EL0.
97249259Sdim    THREAD_POINTER,
98249259Sdim
99249259Sdim    /// Extracts a field of contiguous bits from the source and zero extends
100249259Sdim    /// them into a single register. Arguments are: source; immr; imms. Note
101249259Sdim    /// these are pre-encoded since DAG matching can't cope with combining LSB
102249259Sdim    /// and Width into these values itself.
103249259Sdim    UBFX,
104249259Sdim
105249259Sdim    // Wraps an address which the ISelLowering phase has decided should be
106251662Sdim    // created using the large memory model style: i.e. a sequence of four
107251662Sdim    // movz/movk instructions.
108251662Sdim    WrapperLarge,
109251662Sdim
110251662Sdim    // Wraps an address which the ISelLowering phase has decided should be
111251662Sdim    // created using the small memory model style: i.e. adrp/add or
112249259Sdim    // adrp/mem-op. This exists to prevent bare TargetAddresses which may never
113249259Sdim    // get selected.
114263508Sdim    WrapperSmall,
115263508Sdim
116263508Sdim    // Vector bitwise select
117263508Sdim    NEON_BSL,
118263508Sdim
119263508Sdim    // Vector move immediate
120263508Sdim    NEON_MOVIMM,
121263508Sdim
122263508Sdim    // Vector Move Inverted Immediate
123263508Sdim    NEON_MVNIMM,
124263508Sdim
125263508Sdim    // Vector FP move immediate
126263508Sdim    NEON_FMOVIMM,
127263508Sdim
128263508Sdim    // Vector permute
129263508Sdim    NEON_UZP1,
130263508Sdim    NEON_UZP2,
131263508Sdim    NEON_ZIP1,
132263508Sdim    NEON_ZIP2,
133263508Sdim    NEON_TRN1,
134263508Sdim    NEON_TRN2,
135263508Sdim
136263508Sdim    // Vector Element reverse
137263508Sdim    NEON_REV64,
138263508Sdim    NEON_REV32,
139263508Sdim    NEON_REV16,
140263508Sdim
141263508Sdim    // Vector compare
142263508Sdim    NEON_CMP,
143263508Sdim
144263508Sdim    // Vector compare zero
145263508Sdim    NEON_CMPZ,
146263508Sdim
147263508Sdim    // Vector compare bitwise test
148263508Sdim    NEON_TST,
149263508Sdim
150263508Sdim    // Vector saturating shift
151263508Sdim    NEON_QSHLs,
152263508Sdim    NEON_QSHLu,
153263508Sdim
154263508Sdim    // Vector dup
155263508Sdim    NEON_VDUP,
156263508Sdim
157263508Sdim    // Vector dup by lane
158263508Sdim    NEON_VDUPLANE,
159263508Sdim
160263508Sdim    // Vector extract
161263508Sdim    NEON_VEXTRACT,
162263508Sdim
163263508Sdim    // NEON duplicate lane loads
164263508Sdim    NEON_LD2DUP = ISD::FIRST_TARGET_MEMORY_OPCODE,
165263508Sdim    NEON_LD3DUP,
166263508Sdim    NEON_LD4DUP,
167263508Sdim
168263508Sdim    // NEON loads with post-increment base updates:
169263508Sdim    NEON_LD1_UPD,
170263508Sdim    NEON_LD2_UPD,
171263508Sdim    NEON_LD3_UPD,
172263508Sdim    NEON_LD4_UPD,
173263508Sdim    NEON_LD1x2_UPD,
174263508Sdim    NEON_LD1x3_UPD,
175263508Sdim    NEON_LD1x4_UPD,
176263508Sdim
177263508Sdim    // NEON stores with post-increment base updates:
178263508Sdim    NEON_ST1_UPD,
179263508Sdim    NEON_ST2_UPD,
180263508Sdim    NEON_ST3_UPD,
181263508Sdim    NEON_ST4_UPD,
182263508Sdim    NEON_ST1x2_UPD,
183263508Sdim    NEON_ST1x3_UPD,
184263508Sdim    NEON_ST1x4_UPD,
185263508Sdim
186263508Sdim    // NEON duplicate lane loads with post-increment base updates:
187263508Sdim    NEON_LD2DUP_UPD,
188263508Sdim    NEON_LD3DUP_UPD,
189263508Sdim    NEON_LD4DUP_UPD,
190263508Sdim
191263508Sdim    // NEON lane loads with post-increment base updates:
192263508Sdim    NEON_LD2LN_UPD,
193263508Sdim    NEON_LD3LN_UPD,
194263508Sdim    NEON_LD4LN_UPD,
195263508Sdim
196263508Sdim    // NEON lane store with post-increment base updates:
197263508Sdim    NEON_ST2LN_UPD,
198263508Sdim    NEON_ST3LN_UPD,
199263508Sdim    NEON_ST4LN_UPD
200249259Sdim  };
201249259Sdim}
202249259Sdim
203249259Sdim
204249259Sdimclass AArch64Subtarget;
205249259Sdimclass AArch64TargetMachine;
206249259Sdim
207249259Sdimclass AArch64TargetLowering : public TargetLowering {
208249259Sdimpublic:
209249259Sdim  explicit AArch64TargetLowering(AArch64TargetMachine &TM);
210249259Sdim
211249259Sdim  const char *getTargetNodeName(unsigned Opcode) const;
212249259Sdim
213249259Sdim  CCAssignFn *CCAssignFnForNode(CallingConv::ID CC) const;
214249259Sdim
215249259Sdim  SDValue LowerFormalArguments(SDValue Chain,
216249259Sdim                               CallingConv::ID CallConv, bool isVarArg,
217249259Sdim                               const SmallVectorImpl<ISD::InputArg> &Ins,
218263508Sdim                               SDLoc dl, SelectionDAG &DAG,
219249259Sdim                               SmallVectorImpl<SDValue> &InVals) const;
220249259Sdim
221249259Sdim  SDValue LowerReturn(SDValue Chain,
222249259Sdim                      CallingConv::ID CallConv, bool isVarArg,
223249259Sdim                      const SmallVectorImpl<ISD::OutputArg> &Outs,
224249259Sdim                      const SmallVectorImpl<SDValue> &OutVals,
225263508Sdim                      SDLoc dl, SelectionDAG &DAG) const;
226249259Sdim
227249259Sdim  SDValue LowerCall(CallLoweringInfo &CLI,
228249259Sdim                    SmallVectorImpl<SDValue> &InVals) const;
229249259Sdim
230249259Sdim  SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
231249259Sdim                          CallingConv::ID CallConv, bool IsVarArg,
232249259Sdim                          const SmallVectorImpl<ISD::InputArg> &Ins,
233263508Sdim                          SDLoc dl, SelectionDAG &DAG,
234249259Sdim                          SmallVectorImpl<SDValue> &InVals) const;
235249259Sdim
236263508Sdim  bool isKnownShuffleVector(SDValue Op, SelectionDAG &DAG, SDValue &Res) const;
237249259Sdim
238263508Sdim  SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
239263508Sdim                            const AArch64Subtarget *ST) const;
240249259Sdim
241263508Sdim  SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
242263508Sdim
243263508Sdim  void SaveVarArgRegisters(CCState &CCInfo, SelectionDAG &DAG, SDLoc DL,
244263508Sdim                           SDValue &Chain) const;
245263508Sdim
246249259Sdim  /// IsEligibleForTailCallOptimization - Check whether the call is eligible
247249259Sdim  /// for tail call optimization. Targets which want to do tail call
248249259Sdim  /// optimization should implement this function.
249249259Sdim  bool IsEligibleForTailCallOptimization(SDValue Callee,
250249259Sdim                                    CallingConv::ID CalleeCC,
251249259Sdim                                    bool IsVarArg,
252249259Sdim                                    bool IsCalleeStructRet,
253249259Sdim                                    bool IsCallerStructRet,
254249259Sdim                                    const SmallVectorImpl<ISD::OutputArg> &Outs,
255249259Sdim                                    const SmallVectorImpl<SDValue> &OutVals,
256249259Sdim                                    const SmallVectorImpl<ISD::InputArg> &Ins,
257249259Sdim                                    SelectionDAG& DAG) const;
258249259Sdim
259249259Sdim  /// Finds the incoming stack arguments which overlap the given fixed stack
260249259Sdim  /// object and incorporates their load into the current chain. This prevents
261249259Sdim  /// an upcoming store from clobbering the stack argument before it's used.
262249259Sdim  SDValue addTokenForArgument(SDValue Chain, SelectionDAG &DAG,
263249259Sdim                              MachineFrameInfo *MFI, int ClobberedFI) const;
264249259Sdim
265263508Sdim  EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
266249259Sdim
267249259Sdim  bool DoesCalleeRestoreStack(CallingConv::ID CallCC, bool TailCallOpt) const;
268249259Sdim
269249259Sdim  bool IsTailCallConvention(CallingConv::ID CallCC) const;
270249259Sdim
271249259Sdim  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
272249259Sdim
273249259Sdim  bool isLegalICmpImmediate(int64_t Val) const;
274249259Sdim  SDValue getSelectableIntSetCC(SDValue LHS, SDValue RHS, ISD::CondCode CC,
275263508Sdim                         SDValue &A64cc, SelectionDAG &DAG, SDLoc &dl) const;
276249259Sdim
277249259Sdim  virtual MachineBasicBlock *
278249259Sdim  EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
279249259Sdim
280249259Sdim  MachineBasicBlock *
281249259Sdim  emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *MBB,
282249259Sdim                   unsigned Size, unsigned Opcode) const;
283249259Sdim
284249259Sdim  MachineBasicBlock *
285249259Sdim  emitAtomicBinaryMinMax(MachineInstr *MI, MachineBasicBlock *BB,
286249259Sdim                         unsigned Size, unsigned CmpOp,
287249259Sdim                         A64CC::CondCodes Cond) const;
288249259Sdim  MachineBasicBlock *
289249259Sdim  emitAtomicCmpSwap(MachineInstr *MI, MachineBasicBlock *BB,
290249259Sdim                    unsigned Size) const;
291249259Sdim
292249259Sdim  MachineBasicBlock *
293249259Sdim  EmitF128CSEL(MachineInstr *MI, MachineBasicBlock *MBB) const;
294249259Sdim
295249259Sdim  SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
296249259Sdim  SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
297249259Sdim  SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
298249259Sdim  SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
299249259Sdim  SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
300249259Sdim  SDValue LowerF128ToCall(SDValue Op, SelectionDAG &DAG,
301249259Sdim                          RTLIB::Libcall Call) const;
302249259Sdim  SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
303249259Sdim  SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
304249259Sdim  SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, bool IsSigned) const;
305263508Sdim  SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
306263508Sdim  SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
307251662Sdim
308251662Sdim  SDValue LowerGlobalAddressELFSmall(SDValue Op, SelectionDAG &DAG) const;
309251662Sdim  SDValue LowerGlobalAddressELFLarge(SDValue Op, SelectionDAG &DAG) const;
310249259Sdim  SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const;
311251662Sdim
312263508Sdim  SDValue LowerTLSDescCall(SDValue SymAddr, SDValue DescAddr, SDLoc DL,
313249259Sdim                           SelectionDAG &DAG) const;
314249259Sdim  SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
315249259Sdim  SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG, bool IsSigned) const;
316249259Sdim  SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
317249259Sdim  SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
318249259Sdim  SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
319249259Sdim  SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
320249259Sdim  SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
321249259Sdim  SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
322249259Sdim
323249259Sdim  virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
324249259Sdim
325263508Sdim  /// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
326263508Sdim  /// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
327263508Sdim  /// expanded to FMAs when this method returns true, otherwise fmuladd is
328263508Sdim  /// expanded to fmul + fadd.
329263508Sdim  virtual bool isFMAFasterThanFMulAndFAdd(EVT VT) const;
330249259Sdim
331249259Sdim  ConstraintType getConstraintType(const std::string &Constraint) const;
332249259Sdim
333249259Sdim  ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &Info,
334249259Sdim                                                  const char *Constraint) const;
335249259Sdim  void LowerAsmOperandForConstraint(SDValue Op,
336249259Sdim                                    std::string &Constraint,
337249259Sdim                                    std::vector<SDValue> &Ops,
338249259Sdim                                    SelectionDAG &DAG) const;
339249259Sdim
340249259Sdim  std::pair<unsigned, const TargetRegisterClass*>
341263508Sdim  getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const;
342263508Sdim
343263508Sdim  virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
344263508Sdim                                  unsigned Intrinsic) const LLVM_OVERRIDE;
345263508Sdim
346263508Sdimprotected:
347263508Sdim  std::pair<const TargetRegisterClass*, uint8_t>
348263508Sdim  findRepresentativeClass(MVT VT) const;
349263508Sdim
350249259Sdimprivate:
351249259Sdim  const InstrItineraryData *Itins;
352263508Sdim
353263508Sdim  const AArch64Subtarget *getSubtarget() const {
354263508Sdim    return &getTargetMachine().getSubtarget<AArch64Subtarget>();
355263508Sdim  }
356249259Sdim};
357263508Sdimenum NeonModImmType {
358263508Sdim  Neon_Mov_Imm,
359263508Sdim  Neon_Mvn_Imm
360263508Sdim};
361263508Sdim
362263508Sdimextern SDValue ScanBUILD_VECTOR(SDValue Op, bool &isOnlyLowElement,
363263508Sdim                                bool &usesOnlyOneValue, bool &hasDominantValue,
364263508Sdim                                bool &isConstant, bool &isUNDEF);
365249259Sdim} // namespace llvm
366249259Sdim
367249259Sdim#endif // LLVM_TARGET_AARCH64_ISELLOWERING_H
368