blob: 50af2ade7655b682da67445ca40965a2c1fbe530 [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.
Sirish Pande69295b82012-05-10 20:20:25 +000034 FCONST32,
Krzysztof Parzyszek4fa2a9f2015-04-22 16:43:53 +000035 ALLOCA,
Tony Linthicum1213a7a2011-12-12 21:14:40 +000036 ARGEXTEND,
37
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +000038 AT_GOT, // Index in GOT.
39 AT_PCREL, // Offset relative to PC.
Colin LeMahieu60a99e62015-03-10 20:04:44 +000040
Colin LeMahieu2e3a26d2015-01-16 17:05:27 +000041 CALLv3, // A V3+ call instruction.
42 CALLv3nr, // A V3+ call instruction that doesn't return.
43 CALLR,
44
Tony Linthicum1213a7a2011-12-12 21:14:40 +000045 RET_FLAG, // Return with a flag operand.
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000046 BARRIER, // Memory barrier.
47 JT, // Jump table.
48 CP, // Constant pool.
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000049
Colin LeMahieu777abcb2015-01-07 20:07:28 +000050 POPCOUNT,
Colin LeMahieu383c36e2014-12-05 18:24:06 +000051 COMBINE,
Colin LeMahieubd8d0f32015-03-09 18:34:05 +000052 PACKHL,
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000053 VSPLATB,
54 VSPLATH,
55 SHUFFEB,
56 SHUFFEH,
57 SHUFFOB,
58 SHUFFOH,
59 VSXTBH,
60 VSXTBW,
61 VSRAW,
62 VSRAH,
63 VSRLW,
64 VSRLH,
65 VSHLW,
66 VSHLH,
67 VCMPBEQ,
68 VCMPBGT,
69 VCMPBGTU,
70 VCMPHEQ,
71 VCMPHGT,
72 VCMPHGTU,
73 VCMPWEQ,
74 VCMPWGT,
75 VCMPWGTU,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000076
77 INSERT,
78 INSERTRP,
79 EXTRACTU,
80 EXTRACTURP,
Krzysztof Parzyszekc168c012015-12-03 16:47:20 +000081 VCOMBINE,
Jyotsna Verma5ed51812013-05-01 21:37:34 +000082 TC_RETURN,
Colin LeMahieu68b2e052015-01-06 19:03:20 +000083 EH_RETURN,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000084 DCFETCH,
85
86 OP_END
Tony Linthicum1213a7a2011-12-12 21:14:40 +000087 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000088 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +000089
Eric Christopherd737b762015-02-02 22:11:36 +000090 class HexagonSubtarget;
91
Tony Linthicum1213a7a2011-12-12 21:14:40 +000092 class HexagonTargetLowering : public TargetLowering {
93 int VarArgsFrameOffset; // Frame offset to start of varargs area.
94
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000095 bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
96 const;
Craig Topper18e69f42016-04-15 06:20:21 +000097 void promoteLdStType(MVT VT, MVT PromotedLdStVT);
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000098 const HexagonTargetMachine &HTM;
99 const HexagonSubtarget &Subtarget;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000100
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000101 public:
Eric Christopherd737b762015-02-02 22:11:36 +0000102 explicit HexagonTargetLowering(const TargetMachine &TM,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000103 const HexagonSubtarget &ST);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000104
105 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
106 /// for tail call optimization. Targets which want to do tail call
107 /// optimization should implement this function.
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000108 bool IsEligibleForTailCallOptimization(SDValue Callee,
109 CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
110 bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
111 const SmallVectorImpl<SDValue> &OutVals,
112 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000113
Craig Topper906c2cd2014-04-29 07:58:16 +0000114 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
115 bool isTruncateFree(EVT VT1, EVT VT2) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000116
Craig Topper906c2cd2014-04-29 07:58:16 +0000117 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
Tim Northovera4415852013-08-06 09:12:35 +0000118
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000119 // Should we expand the build vector with shuffles?
120 bool shouldExpandBuildVectorWithShuffles(EVT VT,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000121 unsigned DefinedValues) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000122
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000123 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
Craig Topper906c2cd2014-04-29 07:58:16 +0000124 const char *getTargetNodeName(unsigned Opcode) const override;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000125 SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
126 SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
127 SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
128 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000129 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
130 SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek6895b2c2016-02-18 13:58:38 +0000131 SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000132 SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000133 SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000134 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
135 bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl,
136 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000137 SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
Jyotsna Verma2ba0c0b2013-03-07 19:10:28 +0000138 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek7a737d12016-02-18 15:42:57 +0000139 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
140 SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
141 SelectionDAG &DAG) const;
142 SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
143 SelectionDAG &DAG) const;
144 SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
145 SelectionDAG &DAG) const;
146 SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
147 GlobalAddressSDNode *GA, SDValue *InFlag, EVT PtrVT,
148 unsigned ReturnReg, unsigned char OperandFlags) const;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000149 SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000150
Justin Holewinskiaa583972012-05-25 16:35:28 +0000151 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000152 SmallVectorImpl<SDValue> &InVals) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000153 SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000154 CallingConv::ID CallConv, bool isVarArg,
155 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl,
156 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
157 const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000158
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000159 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
160 SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
161 SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000162 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000163 SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
164 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000165 SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000166
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000167 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv,
168 bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs,
169 const SmallVectorImpl<SDValue> &OutVals, SDLoc dl,
170 SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000171
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000172 bool mayBeEmittedAsTailCall(CallInst *CI) const override;
173 MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI,
174 MachineBasicBlock *BB) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000175
Joseph Tremouletf748c892015-11-07 01:11:31 +0000176 /// If a physical register, this returns the register that receives the
177 /// exception address on entry to an EH pad.
178 unsigned
179 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
180 return Hexagon::R0;
181 }
182
183 /// If a physical register, this returns the register that receives the
184 /// exception typeid on entry to a landing pad.
185 unsigned
186 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
187 return Hexagon::R1;
188 }
189
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000190 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
191 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000192 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
Mehdi Amini44ede332015-07-09 02:09:04 +0000193 EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
194 EVT VT) const override {
Juergen Ributzka34c652d2013-11-13 01:57:54 +0000195 if (!VT.isVector())
196 return MVT::i1;
197 else
198 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000199 }
200
Craig Topper906c2cd2014-04-29 07:58:16 +0000201 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
202 SDValue &Base, SDValue &Offset,
203 ISD::MemIndexedMode &AM,
204 SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000205
Eric Christopher11e4df72015-02-26 22:38:43 +0000206 std::pair<unsigned, const TargetRegisterClass *>
207 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000208 StringRef Constraint, MVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000209
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000210 unsigned
211 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
Daniel Sanders49f643c2015-03-17 14:37:39 +0000212 if (ConstraintCode == "o")
213 return InlineAsm::Constraint_o;
214 else if (ConstraintCode == "v")
215 return InlineAsm::Constraint_v;
216 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
Daniel Sandersbf5b80f2015-03-16 13:13:41 +0000217 }
218
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000219 // Intrinsics
Craig Topper906c2cd2014-04-29 07:58:16 +0000220 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek6895b2c2016-02-18 13:58:38 +0000221 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000222 /// isLegalAddressingMode - Return true if the addressing mode represented
223 /// by AM is legal for this target, for a load/store of the specified type.
224 /// The type may be VoidTy, in which case only return true if the addressing
225 /// mode is legal for a load/store of any legal type.
226 /// TODO: Handle pre/postinc as well.
Mehdi Amini0cdec1e2015-07-09 02:09:40 +0000227 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
228 Type *Ty, unsigned AS) const override;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000229 /// Return true if folding a constant offset with the given GlobalAddress
230 /// is legal. It is frequently not legal in PIC relocation models.
231 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
232
Craig Topper906c2cd2014-04-29 07:58:16 +0000233 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000234
235 /// isLegalICmpImmediate - Return true if the specified immediate is legal
236 /// icmp immediate, that is the target has icmp instructions which can
237 /// compare a register against the immediate without having to materialize
238 /// the immediate into a register.
Craig Topper906c2cd2014-04-29 07:58:16 +0000239 bool isLegalICmpImmediate(int64_t Imm) const override;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000240
Krzysztof Parzyszek2d65ea72016-03-28 15:43:03 +0000241 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
242 unsigned Align, bool *Fast) const override;
243
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000244 /// Returns relocation base for the given PIC jumptable.
245 SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
246 const override;
247
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000248 // Handling of atomic RMW instructions.
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000249 Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
250 AtomicOrdering Ord) const override;
251 Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
252 Value *Addr, AtomicOrdering Ord) const override;
Ahmed Bougacha52468672015-09-11 17:08:28 +0000253 AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000254 bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
Ahmed Bougacha9d677132015-09-11 17:08:17 +0000255 AtomicExpansionKind
256 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
257 return AtomicExpansionKind::LLSC;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000258 }
Krzysztof Parzyszek08ff8882015-11-26 18:38:27 +0000259
260 protected:
261 std::pair<const TargetRegisterClass*, uint8_t>
262 findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
263 const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000264 };
265} // end namespace llvm
266
267#endif // Hexagon_ISELLOWERING_H