blob: cfe24a137dbb56f967ed6f91f821e037725cacb5 [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the interfaces that Hexagon uses to lower LLVM code into a
11// selection DAG.
12//
13//===----------------------------------------------------------------------===//
14
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000015#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
16#define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
Tony Linthicum1213a7a2011-12-12 21:14:40 +000017
Craig Topperb25fda92012-03-17 18:46:09 +000018#include "Hexagon.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000019#include "llvm/CodeGen/CallingConvLower.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/CallingConv.h"
Chandler Carruth802d7552012-12-04 07:12:27 +000021#include "llvm/Target/TargetLowering.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000022
23namespace llvm {
Colin LeMahieu025f8602014-12-08 21:19:18 +000024
25// Return true when the given node fits in a positive half word.
26bool isPositiveHalfWord(SDNode *N);
27
Tony Linthicum1213a7a2011-12-12 21:14:40 +000028 namespace HexagonISD {
Matthias Braund04893f2015-05-07 21:33:59 +000029 enum NodeType : unsigned {
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000030 OP_BEGIN = ISD::BUILTIN_OP_END,
Tony Linthicum1213a7a2011-12-12 21:14:40 +000031
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000032 CONST32 = OP_BEGIN,
Tony Linthicum1213a7a2011-12-12 21:14:40 +000033 CONST32_GP, // For marking data present in GP.
Krzysztof Parzyszek4fa2a9f2015-04-22 16:43:53 +000034 ALLOCA,
Tony Linthicum1213a7a2011-12-12 21:14:40 +000035
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +000036 AT_GOT, // Index in GOT.
37 AT_PCREL, // Offset relative to PC.
Colin LeMahieu60a99e62015-03-10 20:04:44 +000038
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +000039 CALL, // Function call.
40 CALLnr, // Function call that does not return.
Colin LeMahieu2e3a26d2015-01-16 17:05:27 +000041 CALLR,
42
Tony Linthicum1213a7a2011-12-12 21:14:40 +000043 RET_FLAG, // Return with a flag operand.
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000044 BARRIER, // Memory barrier.
45 JT, // Jump table.
46 CP, // Constant pool.
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000047
Colin LeMahieu777abcb2015-01-07 20:07:28 +000048 POPCOUNT,
Colin LeMahieu383c36e2014-12-05 18:24:06 +000049 COMBINE,
Colin LeMahieubd8d0f32015-03-09 18:34:05 +000050 PACKHL,
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000051 VSPLATB,
52 VSPLATH,
53 SHUFFEB,
54 SHUFFEH,
55 SHUFFOB,
56 SHUFFOH,
57 VSXTBH,
58 VSXTBW,
59 VSRAW,
60 VSRAH,
61 VSRLW,
62 VSRLH,
63 VSHLW,
64 VSHLH,
65 VCMPBEQ,
66 VCMPBGT,
67 VCMPBGTU,
68 VCMPHEQ,
69 VCMPHGT,
70 VCMPHGTU,
71 VCMPWEQ,
72 VCMPWGT,
73 VCMPWGTU,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000074
75 INSERT,
76 INSERTRP,
77 EXTRACTU,
78 EXTRACTURP,
Krzysztof Parzyszekc168c012015-12-03 16:47:20 +000079 VCOMBINE,
Krzysztof Parzyszek0bd55a72016-07-29 16:44:27 +000080 VPACK,
Jyotsna Verma5ed51812013-05-01 21:37:34 +000081 TC_RETURN,
Colin LeMahieu68b2e052015-01-06 19:03:20 +000082 EH_RETURN,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000083 DCFETCH,
84
85 OP_END
Tony Linthicum1213a7a2011-12-12 21:14:40 +000086 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000087 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +000088
Eric Christopherd737b762015-02-02 22:11:36 +000089 class HexagonSubtarget;
90
Tony Linthicum1213a7a2011-12-12 21:14:40 +000091 class HexagonTargetLowering : public TargetLowering {
92 int VarArgsFrameOffset; // Frame offset to start of varargs area.
93
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000094 bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
95 const;
Craig Topper18e69f42016-04-15 06:20:21 +000096 void promoteLdStType(MVT VT, MVT PromotedLdStVT);
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000097 const HexagonTargetMachine &HTM;
98 const HexagonSubtarget &Subtarget;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000099
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000100 public:
Eric Christopherd737b762015-02-02 22:11:36 +0000101 explicit HexagonTargetLowering(const TargetMachine &TM,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000102 const HexagonSubtarget &ST);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000103
104 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
105 /// for tail call optimization. Targets which want to do tail call
106 /// optimization should implement this function.
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000107 bool IsEligibleForTailCallOptimization(SDValue Callee,
108 CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
109 bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
110 const SmallVectorImpl<SDValue> &OutVals,
111 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000112
Craig Topper906c2cd2014-04-29 07:58:16 +0000113 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
114 bool isTruncateFree(EVT VT1, EVT VT2) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000115
Craig Topper906c2cd2014-04-29 07:58:16 +0000116 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
Tim Northovera4415852013-08-06 09:12:35 +0000117
Krzysztof Parzyszekbd8ef4b2016-08-19 13:34:31 +0000118 /// Return true if an FMA operation is faster than a pair of mul and add
119 /// instructions. fmuladd intrinsics will be expanded to FMAs when this
120 /// method returns true (and FMAs are legal), otherwise fmuladd is
121 /// expanded to mul + add.
122 bool isFMAFasterThanFMulAndFAdd(EVT) const override;
123
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000124 // Should we expand the build vector with shuffles?
125 bool shouldExpandBuildVectorWithShuffles(EVT VT,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000126 unsigned DefinedValues) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000127
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000128 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
Craig Topper906c2cd2014-04-29 07:58:16 +0000129 const char *getTargetNodeName(unsigned Opcode) const override;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000130 SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
131 SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek0bd55a72016-07-29 16:44:27 +0000132 SDValue LowerEXTRACT_SUBVECTOR_HVX(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000133 SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek0bd55a72016-07-29 16:44:27 +0000134 SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
135 SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000136 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000137 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
138 SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek6895b2c2016-02-18 13:58:38 +0000139 SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000140 SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000141 SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000142 SDValue
143 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
144 const SmallVectorImpl<ISD::InputArg> &Ins,
145 const SDLoc &dl, SelectionDAG &DAG,
146 SmallVectorImpl<SDValue> &InVals) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000147 SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
Jyotsna Verma2ba0c0b2013-03-07 19:10:28 +0000148 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek7a737d12016-02-18 15:42:57 +0000149 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
150 SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
151 SelectionDAG &DAG) const;
152 SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
153 SelectionDAG &DAG) const;
154 SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
155 SelectionDAG &DAG) const;
156 SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
157 GlobalAddressSDNode *GA, SDValue *InFlag, EVT PtrVT,
158 unsigned ReturnReg, unsigned char OperandFlags) const;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000159 SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000160
Justin Holewinskiaa583972012-05-25 16:35:28 +0000161 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000162 SmallVectorImpl<SDValue> &InVals) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000163 SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000164 CallingConv::ID CallConv, bool isVarArg,
165 const SmallVectorImpl<ISD::InputArg> &Ins,
166 const SDLoc &dl, SelectionDAG &DAG,
167 SmallVectorImpl<SDValue> &InVals,
168 const SmallVectorImpl<SDValue> &OutVals,
169 SDValue Callee) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000170
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000171 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
172 SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
173 SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000174 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000175 SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
176 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000177 SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000178
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000179 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
180 const SmallVectorImpl<ISD::OutputArg> &Outs,
181 const SmallVectorImpl<SDValue> &OutVals,
182 const SDLoc &dl, SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000183
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000184 bool mayBeEmittedAsTailCall(CallInst *CI) const override;
Duncan P. N. Exon Smithe4f5e4f2016-06-30 22:52:52 +0000185 MachineBasicBlock *
186 EmitInstrWithCustomInserter(MachineInstr &MI,
187 MachineBasicBlock *BB) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000188
Joseph Tremouletf748c892015-11-07 01:11:31 +0000189 /// If a physical register, this returns the register that receives the
190 /// exception address on entry to an EH pad.
191 unsigned
192 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
193 return Hexagon::R0;
194 }
195
196 /// If a physical register, this returns the register that receives the
197 /// exception typeid on entry to a landing pad.
198 unsigned
199 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
200 return Hexagon::R1;
201 }
202
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000203 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
204 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000205 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
Mehdi Amini44ede332015-07-09 02:09:04 +0000206 EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
207 EVT VT) const override {
Juergen Ributzka34c652d2013-11-13 01:57:54 +0000208 if (!VT.isVector())
209 return MVT::i1;
210 else
211 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000212 }
213
Craig Topper906c2cd2014-04-29 07:58:16 +0000214 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
215 SDValue &Base, SDValue &Offset,
216 ISD::MemIndexedMode &AM,
217 SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000218
Krzysztof Parzyszekca3b5322016-05-18 14:34:51 +0000219 ConstraintType getConstraintType(StringRef Constraint) const override;
220
Eric Christopher11e4df72015-02-26 22:38:43 +0000221 std::pair<unsigned, const TargetRegisterClass *>
222 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000223 StringRef Constraint, MVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000224
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000225 unsigned
226 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
Daniel Sanders49f643c2015-03-17 14:37:39 +0000227 if (ConstraintCode == "o")
228 return InlineAsm::Constraint_o;
Daniel Sanders49f643c2015-03-17 14:37:39 +0000229 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
Daniel Sandersbf5b80f2015-03-16 13:13:41 +0000230 }
231
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000232 // Intrinsics
Craig Topper906c2cd2014-04-29 07:58:16 +0000233 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek6895b2c2016-02-18 13:58:38 +0000234 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000235 /// isLegalAddressingMode - Return true if the addressing mode represented
236 /// by AM is legal for this target, for a load/store of the specified type.
237 /// The type may be VoidTy, in which case only return true if the addressing
238 /// mode is legal for a load/store of any legal type.
239 /// TODO: Handle pre/postinc as well.
Mehdi Amini0cdec1e2015-07-09 02:09:40 +0000240 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
241 Type *Ty, unsigned AS) const override;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000242 /// Return true if folding a constant offset with the given GlobalAddress
243 /// is legal. It is frequently not legal in PIC relocation models.
244 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
245
Craig Topper906c2cd2014-04-29 07:58:16 +0000246 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000247
248 /// isLegalICmpImmediate - Return true if the specified immediate is legal
249 /// icmp immediate, that is the target has icmp instructions which can
250 /// compare a register against the immediate without having to materialize
251 /// the immediate into a register.
Craig Topper906c2cd2014-04-29 07:58:16 +0000252 bool isLegalICmpImmediate(int64_t Imm) const override;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000253
Krzysztof Parzyszek3e409e12016-08-02 18:34:31 +0000254 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
255 unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
256 MachineFunction &MF) const override;
257
Krzysztof Parzyszek2d65ea72016-03-28 15:43:03 +0000258 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
259 unsigned Align, bool *Fast) const override;
260
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000261 /// Returns relocation base for the given PIC jumptable.
262 SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
263 const override;
264
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000265 // Handling of atomic RMW instructions.
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000266 Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
267 AtomicOrdering Ord) const override;
268 Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
269 Value *Addr, AtomicOrdering Ord) const override;
Ahmed Bougacha52468672015-09-11 17:08:28 +0000270 AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000271 bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
Krzysztof Parzyszekf228c952016-06-22 16:07:10 +0000272 bool shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
273
Ahmed Bougacha9d677132015-09-11 17:08:17 +0000274 AtomicExpansionKind
275 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
276 return AtomicExpansionKind::LLSC;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000277 }
Krzysztof Parzyszek08ff8882015-11-26 18:38:27 +0000278
279 protected:
280 std::pair<const TargetRegisterClass*, uint8_t>
281 findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
282 const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000283 };
284} // end namespace llvm
285
286#endif // Hexagon_ISELLOWERING_H