blob: 1a682fcb9f3e7e1a790590925b43ab741c540b2a [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;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000097 void promoteLdStType(EVT VT, EVT 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 Parzyszek21dc8bd2015-12-18 20:19:30 +0000139 SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000140
Justin Holewinskiaa583972012-05-25 16:35:28 +0000141 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000142 SmallVectorImpl<SDValue> &InVals) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000143 SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000144 CallingConv::ID CallConv, bool isVarArg,
145 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl,
146 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
147 const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000148
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000149 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
150 SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
151 SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000152 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000153 SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
154 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000155 SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000156
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000157 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv,
158 bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs,
159 const SmallVectorImpl<SDValue> &OutVals, SDLoc dl,
160 SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000161
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000162 bool mayBeEmittedAsTailCall(CallInst *CI) const override;
163 MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI,
164 MachineBasicBlock *BB) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000165
Joseph Tremouletf748c892015-11-07 01:11:31 +0000166 /// If a physical register, this returns the register that receives the
167 /// exception address on entry to an EH pad.
168 unsigned
169 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
170 return Hexagon::R0;
171 }
172
173 /// If a physical register, this returns the register that receives the
174 /// exception typeid on entry to a landing pad.
175 unsigned
176 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
177 return Hexagon::R1;
178 }
179
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000180 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
181 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000182 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
Mehdi Amini44ede332015-07-09 02:09:04 +0000183 EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
184 EVT VT) const override {
Juergen Ributzka34c652d2013-11-13 01:57:54 +0000185 if (!VT.isVector())
186 return MVT::i1;
187 else
188 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000189 }
190
Craig Topper906c2cd2014-04-29 07:58:16 +0000191 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
192 SDValue &Base, SDValue &Offset,
193 ISD::MemIndexedMode &AM,
194 SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000195
Eric Christopher11e4df72015-02-26 22:38:43 +0000196 std::pair<unsigned, const TargetRegisterClass *>
197 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000198 StringRef Constraint, MVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000199
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000200 unsigned
201 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
Daniel Sanders49f643c2015-03-17 14:37:39 +0000202 if (ConstraintCode == "o")
203 return InlineAsm::Constraint_o;
204 else if (ConstraintCode == "v")
205 return InlineAsm::Constraint_v;
206 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
Daniel Sandersbf5b80f2015-03-16 13:13:41 +0000207 }
208
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000209 // Intrinsics
Craig Topper906c2cd2014-04-29 07:58:16 +0000210 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek6895b2c2016-02-18 13:58:38 +0000211 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000212 /// isLegalAddressingMode - Return true if the addressing mode represented
213 /// by AM is legal for this target, for a load/store of the specified type.
214 /// The type may be VoidTy, in which case only return true if the addressing
215 /// mode is legal for a load/store of any legal type.
216 /// TODO: Handle pre/postinc as well.
Mehdi Amini0cdec1e2015-07-09 02:09:40 +0000217 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
218 Type *Ty, unsigned AS) const override;
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000219 /// Return true if folding a constant offset with the given GlobalAddress
220 /// is legal. It is frequently not legal in PIC relocation models.
221 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
222
Craig Topper906c2cd2014-04-29 07:58:16 +0000223 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000224
225 /// isLegalICmpImmediate - Return true if the specified immediate is legal
226 /// icmp immediate, that is the target has icmp instructions which can
227 /// compare a register against the immediate without having to materialize
228 /// the immediate into a register.
Craig Topper906c2cd2014-04-29 07:58:16 +0000229 bool isLegalICmpImmediate(int64_t Imm) const override;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000230
Krzysztof Parzyszek21dc8bd2015-12-18 20:19:30 +0000231 /// Returns relocation base for the given PIC jumptable.
232 SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
233 const override;
234
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000235 // Handling of atomic RMW instructions.
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000236 Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
237 AtomicOrdering Ord) const override;
238 Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
239 Value *Addr, AtomicOrdering Ord) const override;
Ahmed Bougacha52468672015-09-11 17:08:28 +0000240 AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000241 bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
Ahmed Bougacha9d677132015-09-11 17:08:17 +0000242 AtomicExpansionKind
243 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
244 return AtomicExpansionKind::LLSC;
Krzysztof Parzyszekfeaf7b82015-07-09 14:51:21 +0000245 }
Krzysztof Parzyszek08ff8882015-11-26 18:38:27 +0000246
247 protected:
248 std::pair<const TargetRegisterClass*, uint8_t>
249 findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
250 const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000251 };
252} // end namespace llvm
253
254#endif // Hexagon_ISELLOWERING_H