xref: /NextBSD/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.h (revision 84d351007654069f9643c8e4b4802a7f5f08ee42)
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     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
167     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
getSetCCResultType(const DataLayout &,LLVMContext & C,EVT VT)168     EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
169                            EVT VT) const override {
170       if (!VT.isVector())
171         return MVT::i1;
172       else
173         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
174     }
175 
176     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
177                                     SDValue &Base, SDValue &Offset,
178                                     ISD::MemIndexedMode &AM,
179                                     SelectionDAG &DAG) const override;
180 
181     std::pair<unsigned, const TargetRegisterClass *>
182     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
183                                  StringRef Constraint, MVT VT) const override;
184 
185     unsigned
getInlineAsmMemConstraint(StringRef ConstraintCode)186     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
187       if (ConstraintCode == "o")
188         return InlineAsm::Constraint_o;
189       else if (ConstraintCode == "v")
190         return InlineAsm::Constraint_v;
191       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
192     }
193 
194     // Intrinsics
195     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
196     /// 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.
201     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
202                                Type *Ty, unsigned AS) const override;
203     bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
204 
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.
209     bool isLegalICmpImmediate(int64_t Imm) const override;
210 
211     // Handling of atomic RMW instructions.
hasLoadLinkedStoreConditional()212     bool hasLoadLinkedStoreConditional() const override {
213       return true;
214     }
215     Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
216         AtomicOrdering Ord) const override;
217     Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
218         Value *Addr, AtomicOrdering Ord) const override;
219     bool shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
220     bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
shouldExpandAtomicRMWInIR(AtomicRMWInst * AI)221     AtomicRMWExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI)
222         const override {
223       return AtomicRMWExpansionKind::LLSC;
224     }
225   };
226 } // end namespace llvm
227 
228 #endif    // Hexagon_ISELLOWERING_H
229