[Hexagon] HVX vector register classes and more isel patterns
[oota-llvm.git] / lib / Target / Hexagon / HexagonISelLowering.h
1 //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
2 //
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
15 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
16 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
17
18 #include "Hexagon.h"
19 #include "llvm/CodeGen/CallingConvLower.h"
20 #include "llvm/IR/CallingConv.h"
21 #include "llvm/Target/TargetLowering.h"
22
23 namespace llvm {
24
25 // Return true when the given node fits in a positive half word.
26 bool isPositiveHalfWord(SDNode *N);
27
28   namespace HexagonISD {
29     enum NodeType : unsigned {
30       OP_BEGIN = ISD::BUILTIN_OP_END,
31
32       CONST32 = OP_BEGIN,
33       CONST32_GP,  // For marking data present in GP.
34       FCONST32,
35       ALLOCA,
36       ARGEXTEND,
37
38       PIC_ADD,
39       AT_GOT,
40       AT_PCREL,
41
42       CALLv3,      // A V3+ call instruction.
43       CALLv3nr,    // A V3+ call instruction that doesn't return.
44       CALLR,
45
46       RET_FLAG,    // Return with a flag operand.
47       BR_JT,       // Branch through jump table.
48       BARRIER,     // Memory barrier.
49       JT,          // Jump table.
50       CP,          // Constant pool.
51
52       POPCOUNT,
53       COMBINE,
54       PACKHL,
55       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,
78
79       INSERT,
80       INSERTRP,
81       EXTRACTU,
82       EXTRACTURP,
83       TC_RETURN,
84       EH_RETURN,
85       DCFETCH,
86
87       OP_END
88     };
89   }
90
91   class HexagonSubtarget;
92
93   class HexagonTargetLowering : public TargetLowering {
94     int VarArgsFrameOffset;   // Frame offset to start of varargs area.
95
96     bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
97         const;
98     void promoteLdStType(EVT VT, EVT PromotedLdStVT);
99     const HexagonTargetMachine &HTM;
100     const HexagonSubtarget &Subtarget;
101
102   public:
103     explicit HexagonTargetLowering(const TargetMachine &TM,
104                                    const HexagonSubtarget &ST);
105
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.
109     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;
114
115     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
116     bool isTruncateFree(EVT VT1, EVT VT2) const override;
117
118     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
119
120     // Should we expand the build vector with shuffles?
121     bool shouldExpandBuildVectorWithShuffles(EVT VT,
122         unsigned DefinedValues) const override;
123
124     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
125     const char *getTargetNodeName(unsigned Opcode) const override;
126     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;
131     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;
134     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
135     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;
138     SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
139     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
140
141     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
142         SmallVectorImpl<SDValue> &InVals) const override;
143     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
144         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;
148
149     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
150     SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
151     SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
152     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
153     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
154     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
155     SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
156
157     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;
161
162     bool mayBeEmittedAsTailCall(CallInst *CI) const override;
163     MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI,
164         MachineBasicBlock *BB) const override;
165
166     /// 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
180     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
181     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
182     EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
183                            EVT VT) const override {
184       if (!VT.isVector())
185         return MVT::i1;
186       else
187         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
188     }
189
190     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
191                                     SDValue &Base, SDValue &Offset,
192                                     ISD::MemIndexedMode &AM,
193                                     SelectionDAG &DAG) const override;
194
195     std::pair<unsigned, const TargetRegisterClass *>
196     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
197                                  StringRef Constraint, MVT VT) const override;
198
199     unsigned
200     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
201       if (ConstraintCode == "o")
202         return InlineAsm::Constraint_o;
203       else if (ConstraintCode == "v")
204         return InlineAsm::Constraint_v;
205       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
206     }
207
208     // Intrinsics
209     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
210     /// isLegalAddressingMode - Return true if the addressing mode represented
211     /// by AM is legal for this target, for a load/store of the specified type.
212     /// The type may be VoidTy, in which case only return true if the addressing
213     /// mode is legal for a load/store of any legal type.
214     /// TODO: Handle pre/postinc as well.
215     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
216                                Type *Ty, unsigned AS) const override;
217     bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
218
219     /// isLegalICmpImmediate - Return true if the specified immediate is legal
220     /// icmp immediate, that is the target has icmp instructions which can
221     /// compare a register against the immediate without having to materialize
222     /// the immediate into a register.
223     bool isLegalICmpImmediate(int64_t Imm) const override;
224
225     // Handling of atomic RMW instructions.
226     Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
227         AtomicOrdering Ord) const override;
228     Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
229         Value *Addr, AtomicOrdering Ord) const override;
230     AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
231     bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
232     AtomicExpansionKind
233     shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
234       return AtomicExpansionKind::LLSC;
235     }
236   };
237 } // end namespace llvm
238
239 #endif    // Hexagon_ISELLOWERING_H