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 {
30       FIRST_NUMBER = ISD::BUILTIN_OP_END,
31 
32       CONST32,
33       CONST32_GP,  // For marking data present in GP.
34       CONST32_Int_Real,
35       FCONST32,
36       SETCC,
37       ADJDYNALLOC,
38       ARGEXTEND,
39 
40       PIC_ADD,
41       AT_GOT,
42       AT_PCREL,
43 
44       CMPICC,      // Compare two GPR operands, set icc.
45       CMPFCC,      // Compare two FP operands, set fcc.
46       BRICC,       // Branch to dest on icc condition
47       BRFCC,       // Branch to dest on fcc condition
48       SELECT_ICC,  // Select between two values using the current ICC flags.
49       SELECT_FCC,  // Select between two values using the current FCC flags.
50 
51       Hi, Lo,      // Hi/Lo operations, typically on a global address.
52 
53       FTOI,        // FP to Int within a FP register.
54       ITOF,        // Int to FP within a FP register.
55 
56       CALLv3,      // A V3+ call instruction.
57       CALLv3nr,    // A V3+ call instruction that doesn't return.
58       CALLR,
59 
60       RET_FLAG,    // Return with a flag operand.
61       BR_JT,       // Branch through jump table.
62       BARRIER,     // Memory barrier.
63       JT,          // Jump table.
64       CP,          // Constant pool.
65       POPCOUNT,
66       COMBINE,
67       PACKHL,
68       VSPLATB,
69       VSPLATH,
70       SHUFFEB,
71       SHUFFEH,
72       SHUFFOB,
73       SHUFFOH,
74       VSXTBH,
75       VSXTBW,
76       VSRAW,
77       VSRAH,
78       VSRLW,
79       VSRLH,
80       VSHLW,
81       VSHLH,
82       VCMPBEQ,
83       VCMPBGT,
84       VCMPBGTU,
85       VCMPHEQ,
86       VCMPHGT,
87       VCMPHGTU,
88       VCMPWEQ,
89       VCMPWGT,
90       VCMPWGTU,
91       INSERT_ri,
92       INSERT_rd,
93       INSERT_riv,
94       INSERT_rdv,
95       EXTRACTU_ri,
96       EXTRACTU_rd,
97       EXTRACTU_riv,
98       EXTRACTU_rdv,
99       TC_RETURN,
100       EH_RETURN,
101       DCFETCH
102     };
103   }
104 
105   class HexagonSubtarget;
106 
107   class HexagonTargetLowering : public TargetLowering {
108     int VarArgsFrameOffset;   // Frame offset to start of varargs area.
109 
110     bool CanReturnSmallStruct(const Function* CalleeFn,
111                               unsigned& RetSize) const;
112 
113     void promoteLdStType(EVT VT, EVT PromotedLdStVT);
114 
115   public:
116     const HexagonSubtarget *Subtarget;
117     explicit HexagonTargetLowering(const TargetMachine &TM,
118                                    const HexagonSubtarget &Subtarget);
119 
120     /// IsEligibleForTailCallOptimization - Check whether the call is eligible
121     /// for tail call optimization. Targets which want to do tail call
122     /// optimization should implement this function.
123     bool
124     IsEligibleForTailCallOptimization(SDValue Callee,
125                                       CallingConv::ID CalleeCC,
126                                       bool isVarArg,
127                                       bool isCalleeStructRet,
128                                       bool isCallerStructRet,
129                                       const
130                                       SmallVectorImpl<ISD::OutputArg> &Outs,
131                                       const SmallVectorImpl<SDValue> &OutVals,
132                                       const SmallVectorImpl<ISD::InputArg> &Ins,
133                                       SelectionDAG& DAG) const;
134 
135     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
136     bool isTruncateFree(EVT VT1, EVT VT2) const override;
137 
138     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
139 
140     // Should we expand the build vector with shuffles?
141     bool shouldExpandBuildVectorWithShuffles(EVT VT,
142                                         unsigned DefinedValues) const override;
143 
144     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
145     const char *getTargetNodeName(unsigned Opcode) const override;
146     SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
147     SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
148     SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
149     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
150     SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
151     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
152     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
153     SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
154     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
155     SDValue LowerFormalArguments(SDValue Chain,
156                                  CallingConv::ID CallConv, bool isVarArg,
157                                  const SmallVectorImpl<ISD::InputArg> &Ins,
158                                  SDLoc dl, SelectionDAG &DAG,
159                                  SmallVectorImpl<SDValue> &InVals) const override;
160     SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
161     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
162 
163     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
164                       SmallVectorImpl<SDValue> &InVals) const override;
165 
166     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
167                             CallingConv::ID CallConv, bool isVarArg,
168                             const SmallVectorImpl<ISD::InputArg> &Ins,
169                             SDLoc dl, SelectionDAG &DAG,
170                             SmallVectorImpl<SDValue> &InVals,
171                             const SmallVectorImpl<SDValue> &OutVals,
172                             SDValue Callee) const;
173 
174     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
175     SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
176     SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
177     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
178     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
179     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
180     SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
181 
182     SDValue LowerReturn(SDValue Chain,
183                         CallingConv::ID CallConv, bool isVarArg,
184                         const SmallVectorImpl<ISD::OutputArg> &Outs,
185                         const SmallVectorImpl<SDValue> &OutVals,
186                         SDLoc dl, SelectionDAG &DAG) const override;
187 
188     MachineBasicBlock *
189     EmitInstrWithCustomInserter(MachineInstr *MI,
190                                 MachineBasicBlock *BB) const override;
191 
192     SDValue  LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
193     SDValue  LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
getSetCCResultType(LLVMContext & C,EVT VT)194     EVT getSetCCResultType(LLVMContext &C, EVT VT) const override {
195       if (!VT.isVector())
196         return MVT::i1;
197       else
198         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
199     }
200 
201     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
202                                     SDValue &Base, SDValue &Offset,
203                                     ISD::MemIndexedMode &AM,
204                                     SelectionDAG &DAG) const override;
205 
206     std::pair<unsigned, const TargetRegisterClass *>
207     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
208                                  const std::string &Constraint,
209                                  MVT VT) const override;
210 
getInlineAsmMemConstraint(const std::string & ConstraintCode)211     unsigned getInlineAsmMemConstraint(
212         const std::string &ConstraintCode) const override {
213       if (ConstraintCode == "o")
214         return InlineAsm::Constraint_o;
215       else if (ConstraintCode == "v")
216         return InlineAsm::Constraint_v;
217       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
218     }
219 
220     // Intrinsics
221     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
222     /// 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.
227     bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
228     bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
229 
230     /// isLegalICmpImmediate - Return true if the specified immediate is legal
231     /// icmp immediate, that is the target has icmp instructions which can
232     /// compare a register against the immediate without having to materialize
233     /// the immediate into a register.
234     bool isLegalICmpImmediate(int64_t Imm) const override;
235   };
236 } // end namespace llvm
237 
238 #endif    // Hexagon_ISELLOWERING_H
239