1
//===-- ARMISelLowering.h - ARM DAG Lowering Interface ----------*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
// This file defines the interfaces that ARM uses to lower LLVM code into a
13
//===----------------------------------------------------------------------===//
15
#ifndef ARMISELLOWERING_H
16
#define ARMISELLOWERING_H
18
#include "ARMSubtarget.h"
19
#include "llvm/Target/TargetLowering.h"
20
#include "llvm/CodeGen/SelectionDAG.h"
21
#include "llvm/CodeGen/CallingConvLower.h"
25
class ARMConstantPoolValue;
28
// ARM Specific DAG Nodes
30
// Start the numbering where the builtin ops and target ops leave off.
31
FIRST_NUMBER = ISD::BUILTIN_OP_END,
33
Wrapper, // Wrapper - A wrapper node for TargetConstantPool,
34
// TargetExternalSymbol, and TargetGlobalAddress.
35
WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable
37
CALL, // Function call.
38
CALL_PRED, // Function call that's predicable.
39
CALL_NOLINK, // Function call with branch not branch-and-link.
40
tCALL, // Thumb function call.
41
BRCOND, // Conditional branch.
42
BR_JT, // Jumptable branch.
43
BR2_JT, // Jumptable branch (2 level - jumptable entry is a jump).
44
RET_FLAG, // Return with a flag operand.
46
PIC_ADD, // Add with a PC operand and a PIC label.
48
CMP, // ARM compare instructions.
49
CMPZ, // ARM compare that sets only Z flag.
50
CMPFP, // ARM VFP compare instruction, sets FPSCR.
51
CMPFPw0, // ARM VFP compare against zero instruction, sets FPSCR.
52
FMSTAT, // ARM fmstat instruction.
53
CMOV, // ARM conditional move instructions.
54
CNEG, // ARM conditional negate instructions.
56
RBIT, // ARM bitreverse instruction
58
FTOSI, // FP to sint within a FP register.
59
FTOUI, // FP to uint within a FP register.
60
SITOF, // sint to FP within a FP register.
61
UITOF, // uint to FP within a FP register.
63
SRL_FLAG, // V,Flag = srl_flag X -> srl X, 1 + save carry out.
64
SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out.
65
RRX, // V = RRX X, Flag -> srl X, 1 + shift in carry flag.
67
VMOVRRD, // double to two gprs.
68
VMOVDRR, // Two gprs to double.
70
EH_SJLJ_SETJMP, // SjLj exception handling setjmp.
71
EH_SJLJ_LONGJMP, // SjLj exception handling longjmp.
75
DYN_ALLOC, // Dynamic allocation on the stack.
77
MEMBARRIER, // Memory barrier
78
SYNCBARRIER, // Memory sync barrier
80
VCEQ, // Vector compare equal.
81
VCGE, // Vector compare greater than or equal.
82
VCGEU, // Vector compare unsigned greater than or equal.
83
VCGT, // Vector compare greater than.
84
VCGTU, // Vector compare unsigned greater than.
85
VTST, // Vector test bits.
87
// Vector shift by immediate:
89
VSHRs, // ...right (signed)
90
VSHRu, // ...right (unsigned)
91
VSHLLs, // ...left long (signed)
92
VSHLLu, // ...left long (unsigned)
93
VSHLLi, // ...left long (with maximum shift count)
94
VSHRN, // ...right narrow
96
// Vector rounding shift by immediate:
97
VRSHRs, // ...right (signed)
98
VRSHRu, // ...right (unsigned)
99
VRSHRN, // ...right narrow
101
// Vector saturating shift by immediate:
102
VQSHLs, // ...left (signed)
103
VQSHLu, // ...left (unsigned)
104
VQSHLsu, // ...left (signed to unsigned)
105
VQSHRNs, // ...right narrow (signed)
106
VQSHRNu, // ...right narrow (unsigned)
107
VQSHRNsu, // ...right narrow (signed to unsigned)
109
// Vector saturating rounding shift by immediate:
110
VQRSHRNs, // ...right narrow (signed)
111
VQRSHRNu, // ...right narrow (unsigned)
112
VQRSHRNsu, // ...right narrow (signed to unsigned)
114
// Vector shift and insert:
118
// Vector get lane (VMOV scalar to ARM core register)
119
// (These are used for 8- and 16-bit element types only.)
120
VGETLANEu, // zero-extend vector extract element
121
VGETLANEs, // sign-extend vector extract element
129
VREV64, // reverse elements within 64-bit doublewords
130
VREV32, // reverse elements within 32-bit words
131
VREV16, // reverse elements within 16-bit halfwords
132
VZIP, // zip (interleave)
133
VUZP, // unzip (deinterleave)
136
// Floating-point max and min:
142
/// Define some predicates that are used for node matching.
144
/// getVMOVImm - If this is a build_vector of constants which can be
145
/// formed by using a VMOV instruction of the specified element size,
146
/// return the constant being splatted. The ByteSize field indicates the
147
/// number of bytes of each element [1248].
148
SDValue getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);
150
/// getVFPf32Imm / getVFPf64Imm - If the given fp immediate can be
151
/// materialized with a VMOV.f32 / VMOV.f64 (i.e. fconsts / fconstd)
152
/// instruction, returns its 8-bit integer representation. Otherwise,
154
int getVFPf32Imm(const APFloat &FPImm);
155
int getVFPf64Imm(const APFloat &FPImm);
158
//===--------------------------------------------------------------------===//
159
// ARMTargetLowering - ARM Implementation of the TargetLowering interface
161
class ARMTargetLowering : public TargetLowering {
162
int VarArgsFrameIndex; // FrameIndex for start of varargs area.
164
explicit ARMTargetLowering(TargetMachine &TM);
166
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
168
/// ReplaceNodeResults - Replace the results of node with an illegal result
169
/// type with new values built out of custom code.
171
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
174
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
176
virtual const char *getTargetNodeName(unsigned Opcode) const;
178
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
179
MachineBasicBlock *MBB,
180
DenseMap<MachineBasicBlock*, MachineBasicBlock*>*) const;
182
/// allowsUnalignedMemoryAccesses - Returns true if the target allows
183
/// unaligned memory accesses. of the specified type.
184
/// FIXME: Add getOptimalMemOpType to implement memcpy with NEON?
185
virtual bool allowsUnalignedMemoryAccesses(EVT VT) const;
187
/// isLegalAddressingMode - Return true if the addressing mode represented
188
/// by AM is legal for this target, for a load/store of the specified type.
189
virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const;
190
bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const;
192
/// isLegalICmpImmediate - Return true if the specified immediate is legal
193
/// icmp immediate, that is the target has icmp instructions which can compare
194
/// a register against the immediate without having to materialize the
195
/// immediate into a register.
196
virtual bool isLegalICmpImmediate(int64_t Imm) const;
198
/// getPreIndexedAddressParts - returns true by value, base pointer and
199
/// offset pointer and addressing mode by reference if the node's address
200
/// can be legally represented as pre-indexed load / store address.
201
virtual bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,
203
ISD::MemIndexedMode &AM,
204
SelectionDAG &DAG) const;
206
/// getPostIndexedAddressParts - returns true by value, base pointer and
207
/// offset pointer and addressing mode by reference if this node can be
208
/// combined with a load / store to form a post-indexed load / store.
209
virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
210
SDValue &Base, SDValue &Offset,
211
ISD::MemIndexedMode &AM,
212
SelectionDAG &DAG) const;
214
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
218
const SelectionDAG &DAG,
219
unsigned Depth) const;
222
ConstraintType getConstraintType(const std::string &Constraint) const;
223
std::pair<unsigned, const TargetRegisterClass*>
224
getRegForInlineAsmConstraint(const std::string &Constraint,
226
std::vector<unsigned>
227
getRegClassForInlineAsmConstraint(const std::string &Constraint,
230
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
231
/// vector. If it is invalid, don't add anything to Ops. If hasMemory is
232
/// true it means one of the asm constraint of the inline asm instruction
233
/// being processed is 'm'.
234
virtual void LowerAsmOperandForConstraint(SDValue Op,
235
char ConstraintLetter,
237
std::vector<SDValue> &Ops,
238
SelectionDAG &DAG) const;
240
virtual const ARMSubtarget* getSubtarget() {
244
/// getFunctionAlignment - Return the Log2 alignment of this function.
245
virtual unsigned getFunctionAlignment(const Function *F) const;
247
bool isShuffleMaskLegal(const SmallVectorImpl<int> &M, EVT VT) const;
248
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
250
/// isFPImmLegal - Returns true if the target can instruction select the
251
/// specified FP immediate natively. If false, the legalizer will
252
/// materialize the FP immediate as a load from a constant pool.
253
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
256
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
257
/// make the right decision when generating code for different targets.
258
const ARMSubtarget *Subtarget;
260
/// ARMPCLabelIndex - Keep track of the number of ARM PC labels created.
262
unsigned ARMPCLabelIndex;
264
void addTypeForNEON(EVT VT, EVT PromotedLdStVT, EVT PromotedBitwiseVT);
265
void addDRTypeForNEON(EVT VT);
266
void addQRTypeForNEON(EVT VT);
268
typedef SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPassVector;
269
void PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG,
270
SDValue Chain, SDValue &Arg,
271
RegsToPassVector &RegsToPass,
272
CCValAssign &VA, CCValAssign &NextVA,
274
SmallVector<SDValue, 8> &MemOpChains,
275
ISD::ArgFlagsTy Flags);
276
SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
277
SDValue &Root, SelectionDAG &DAG, DebugLoc dl);
279
CCAssignFn *CCAssignFnForNode(CallingConv::ID CC, bool Return, bool isVarArg) const;
280
SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg,
281
DebugLoc dl, SelectionDAG &DAG,
282
const CCValAssign &VA,
283
ISD::ArgFlagsTy Flags);
284
SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG);
285
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
286
const ARMSubtarget *Subtarget);
287
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG);
288
SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG);
289
SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG);
290
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
291
SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
293
SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,
295
SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG);
296
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG);
297
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
298
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG);
299
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG);
300
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG);
301
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG);
302
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG);
304
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
306
SDValue Dst, SDValue Src,
307
SDValue Size, unsigned Align,
309
const Value *DstSV, uint64_t DstSVOff,
310
const Value *SrcSV, uint64_t SrcSVOff);
311
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
312
CallingConv::ID CallConv, bool isVarArg,
313
const SmallVectorImpl<ISD::InputArg> &Ins,
314
DebugLoc dl, SelectionDAG &DAG,
315
SmallVectorImpl<SDValue> &InVals);
318
LowerFormalArguments(SDValue Chain,
319
CallingConv::ID CallConv, bool isVarArg,
320
const SmallVectorImpl<ISD::InputArg> &Ins,
321
DebugLoc dl, SelectionDAG &DAG,
322
SmallVectorImpl<SDValue> &InVals);
325
LowerCall(SDValue Chain, SDValue Callee,
326
CallingConv::ID CallConv, bool isVarArg,
328
const SmallVectorImpl<ISD::OutputArg> &Outs,
329
const SmallVectorImpl<ISD::InputArg> &Ins,
330
DebugLoc dl, SelectionDAG &DAG,
331
SmallVectorImpl<SDValue> &InVals);
334
LowerReturn(SDValue Chain,
335
CallingConv::ID CallConv, bool isVarArg,
336
const SmallVectorImpl<ISD::OutputArg> &Outs,
337
DebugLoc dl, SelectionDAG &DAG);
339
SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
340
SDValue &ARMCC, SelectionDAG &DAG, DebugLoc dl);
342
MachineBasicBlock *EmitAtomicCmpSwap(MachineInstr *MI,
343
MachineBasicBlock *BB,
344
unsigned Size) const;
345
MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI,
346
MachineBasicBlock *BB,
348
unsigned BinOpcode) const;
353
#endif // ARMISELLOWERING_H