blob: ba8b9cd9fe5cd4f550220f0efc0d460791181b22 [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
Colin LeMahieu60a99e62015-03-10 20:04:44 +000038 PIC_ADD,
39 AT_GOT,
40 AT_PCREL,
41
Colin LeMahieu2e3a26d2015-01-16 17:05:27 +000042 CALLv3, // A V3+ call instruction.
43 CALLv3nr, // A V3+ call instruction that doesn't return.
44 CALLR,
45
Tony Linthicum1213a7a2011-12-12 21:14:40 +000046 RET_FLAG, // Return with a flag operand.
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000047 BR_JT, // Branch through jump table.
48 BARRIER, // Memory barrier.
49 JT, // Jump table.
50 CP, // Constant pool.
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000051
Colin LeMahieu777abcb2015-01-07 20:07:28 +000052 POPCOUNT,
Colin LeMahieu383c36e2014-12-05 18:24:06 +000053 COMBINE,
Colin LeMahieubd8d0f32015-03-09 18:34:05 +000054 PACKHL,
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000055 VSPLATB,
56 VSPLATH,
57 SHUFFEB,
58 SHUFFEH,
59 SHUFFOB,
60 SHUFFOH,
61 VSXTBH,
62 VSXTBW,
63 VSRAW,
64 VSRAH,
65 VSRLW,
66 VSRLH,
67 VSHLW,
68 VSHLH,
69 VCMPBEQ,
70 VCMPBGT,
71 VCMPBGTU,
72 VCMPHEQ,
73 VCMPHGT,
74 VCMPHGTU,
75 VCMPWEQ,
76 VCMPWGT,
77 VCMPWGTU,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000078
79 INSERT,
80 INSERTRP,
81 EXTRACTU,
82 EXTRACTURP,
Jyotsna Verma5ed51812013-05-01 21:37:34 +000083 TC_RETURN,
Colin LeMahieu68b2e052015-01-06 19:03:20 +000084 EH_RETURN,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000085 DCFETCH,
86
87 OP_END
Tony Linthicum1213a7a2011-12-12 21:14:40 +000088 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000089 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +000090
Eric Christopherd737b762015-02-02 22:11:36 +000091 class HexagonSubtarget;
92
Tony Linthicum1213a7a2011-12-12 21:14:40 +000093 class HexagonTargetLowering : public TargetLowering {
94 int VarArgsFrameOffset; // Frame offset to start of varargs area.
95
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000096 bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
97 const;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +000098 void promoteLdStType(EVT VT, EVT PromotedLdStVT);
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +000099 const HexagonTargetMachine &HTM;
100 const HexagonSubtarget &Subtarget;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000101
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000102 public:
Eric Christopherd737b762015-02-02 22:11:36 +0000103 explicit HexagonTargetLowering(const TargetMachine &TM,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000104 const HexagonSubtarget &ST);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000105
106 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
107 /// for tail call optimization. Targets which want to do tail call
108 /// optimization should implement this function.
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000109 bool IsEligibleForTailCallOptimization(SDValue Callee,
110 CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
111 bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
112 const SmallVectorImpl<SDValue> &OutVals,
113 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000114
Craig Topper906c2cd2014-04-29 07:58:16 +0000115 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
116 bool isTruncateFree(EVT VT1, EVT VT2) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000117
Craig Topper906c2cd2014-04-29 07:58:16 +0000118 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
Tim Northovera4415852013-08-06 09:12:35 +0000119
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000120 // Should we expand the build vector with shuffles?
121 bool shouldExpandBuildVectorWithShuffles(EVT VT,
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000122 unsigned DefinedValues) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000123
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000124 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
Craig Topper906c2cd2014-04-29 07:58:16 +0000125 const char *getTargetNodeName(unsigned Opcode) const override;
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000126 SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
127 SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
128 SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
129 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
130 SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000131 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
132 SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
133 SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000134 SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000135 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
136 bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl,
137 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000138 SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
Jyotsna Verma2ba0c0b2013-03-07 19:10:28 +0000139 SDValue LowerBlockAddress(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
Krzysztof Parzyszek952d9512015-04-22 21:17:00 +0000166 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
167 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
Mehdi Amini44ede332015-07-09 02:09:04 +0000168 EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
169 EVT VT) const override {
Juergen Ributzka34c652d2013-11-13 01:57:54 +0000170 if (!VT.isVector())
171 return MVT::i1;
172 else
173 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000174 }
175
Craig Topper906c2cd2014-04-29 07:58:16 +0000176 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
177 SDValue &Base, SDValue &Offset,
178 ISD::MemIndexedMode &AM,
179 SelectionDAG &DAG) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000180
Eric Christopher11e4df72015-02-26 22:38:43 +0000181 std::pair<unsigned, const TargetRegisterClass *>
182 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000183 StringRef Constraint, MVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000184
Benjamin Kramer9bfb6272015-07-05 19:29:18 +0000185 unsigned
186 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
Daniel Sanders49f643c2015-03-17 14:37:39 +0000187 if (ConstraintCode == "o")
188 return InlineAsm::Constraint_o;
189 else if (ConstraintCode == "v")
190 return InlineAsm::Constraint_v;
191 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
Daniel Sandersbf5b80f2015-03-16 13:13:41 +0000192 }
193
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000194 // Intrinsics
Craig Topper906c2cd2014-04-29 07:58:16 +0000195 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000196 /// isLegalAddressingMode - Return true if the addressing mode represented
197 /// by AM is legal for this target, for a load/store of the specified type.
198 /// The type may be VoidTy, in which case only return true if the addressing
199 /// mode is legal for a load/store of any legal type.
200 /// TODO: Handle pre/postinc as well.
Mehdi Amini0cdec1e2015-07-09 02:09:40 +0000201 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
202 Type *Ty, unsigned AS) const override;
Craig Topper906c2cd2014-04-29 07:58:16 +0000203 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000204
205 /// isLegalICmpImmediate - Return true if the specified immediate is legal
206 /// icmp immediate, that is the target has icmp instructions which can
207 /// compare a register against the immediate without having to materialize
208 /// the immediate into a register.
Craig Topper906c2cd2014-04-29 07:58:16 +0000209 bool isLegalICmpImmediate(int64_t Imm) const override;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000210 };
211} // end namespace llvm
212
213#endif // Hexagon_ISELLOWERING_H