/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Sparc/SparcISelLowering.h
Line | Count | Source |
1 | | //===-- SparcISelLowering.h - Sparc 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 Sparc uses to lower LLVM code into a |
11 | | // selection DAG. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #ifndef LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H |
16 | | #define LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H |
17 | | |
18 | | #include "Sparc.h" |
19 | | #include "llvm/Target/TargetLowering.h" |
20 | | |
21 | | namespace llvm { |
22 | | class SparcSubtarget; |
23 | | |
24 | | namespace SPISD { |
25 | | enum NodeType : unsigned { |
26 | | FIRST_NUMBER = ISD::BUILTIN_OP_END, |
27 | | CMPICC, // Compare two GPR operands, set icc+xcc. |
28 | | CMPFCC, // Compare two FP operands, set fcc. |
29 | | BRICC, // Branch to dest on icc condition |
30 | | BRXCC, // Branch to dest on xcc condition (64-bit only). |
31 | | BRFCC, // Branch to dest on fcc condition |
32 | | SELECT_ICC, // Select between two values using the current ICC flags. |
33 | | SELECT_XCC, // Select between two values using the current XCC flags. |
34 | | SELECT_FCC, // Select between two values using the current FCC flags. |
35 | | |
36 | | EH_SJLJ_SETJMP, // builtin setjmp operation |
37 | | EH_SJLJ_LONGJMP, // builtin longjmp operation |
38 | | |
39 | | Hi, Lo, // Hi/Lo operations, typically on a global address. |
40 | | |
41 | | FTOI, // FP to Int within a FP register. |
42 | | ITOF, // Int to FP within a FP register. |
43 | | FTOX, // FP to Int64 within a FP register. |
44 | | XTOF, // Int64 to FP within a FP register. |
45 | | |
46 | | CALL, // A call instruction. |
47 | | RET_FLAG, // Return with a flag operand. |
48 | | GLOBAL_BASE_REG, // Global base reg for PIC. |
49 | | FLUSHW, // FLUSH register windows to stack. |
50 | | |
51 | | TLS_ADD, // For Thread Local Storage (TLS). |
52 | | TLS_LD, |
53 | | TLS_CALL |
54 | | }; |
55 | | } |
56 | | |
57 | | class SparcTargetLowering : public TargetLowering { |
58 | | const SparcSubtarget *Subtarget; |
59 | | public: |
60 | | SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI); |
61 | | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
62 | | |
63 | | bool useSoftFloat() const override; |
64 | | |
65 | | /// computeKnownBitsForTargetNode - Determine which of the bits specified |
66 | | /// in Mask are known to be either zero or one and return them in the |
67 | | /// KnownZero/KnownOne bitsets. |
68 | | void computeKnownBitsForTargetNode(const SDValue Op, |
69 | | KnownBits &Known, |
70 | | const APInt &DemandedElts, |
71 | | const SelectionDAG &DAG, |
72 | | unsigned Depth = 0) const override; |
73 | | |
74 | | MachineBasicBlock * |
75 | | EmitInstrWithCustomInserter(MachineInstr &MI, |
76 | | MachineBasicBlock *MBB) const override; |
77 | | |
78 | | const char *getTargetNodeName(unsigned Opcode) const override; |
79 | | |
80 | | ConstraintType getConstraintType(StringRef Constraint) const override; |
81 | | ConstraintWeight |
82 | | getSingleConstraintMatchWeight(AsmOperandInfo &info, |
83 | | const char *constraint) const override; |
84 | | void LowerAsmOperandForConstraint(SDValue Op, |
85 | | std::string &Constraint, |
86 | | std::vector<SDValue> &Ops, |
87 | | SelectionDAG &DAG) const override; |
88 | | |
89 | | unsigned |
90 | 19 | getInlineAsmMemConstraint(StringRef ConstraintCode) const override { |
91 | 19 | if (ConstraintCode == "o") |
92 | 2 | return InlineAsm::Constraint_o; |
93 | 17 | return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); |
94 | 19 | } |
95 | | |
96 | | std::pair<unsigned, const TargetRegisterClass *> |
97 | | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
98 | | StringRef Constraint, MVT VT) const override; |
99 | | |
100 | | bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; |
101 | 1.02k | MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { |
102 | 1.02k | return MVT::i32; |
103 | 1.02k | } |
104 | | |
105 | | unsigned getRegisterByName(const char* RegName, EVT VT, |
106 | | SelectionDAG &DAG) const override; |
107 | | |
108 | | /// If a physical register, this returns the register that receives the |
109 | | /// exception address on entry to an EH pad. |
110 | | unsigned |
111 | 8 | getExceptionPointerRegister(const Constant *PersonalityFn) const override { |
112 | 8 | return SP::I0; |
113 | 8 | } |
114 | | |
115 | | /// If a physical register, this returns the register that receives the |
116 | | /// exception typeid on entry to a landing pad. |
117 | | unsigned |
118 | 4 | getExceptionSelectorRegister(const Constant *PersonalityFn) const override { |
119 | 4 | return SP::I1; |
120 | 4 | } |
121 | | |
122 | | /// Override to support customized stack guard loading. |
123 | | bool useLoadStackGuardNode() const override; |
124 | | void insertSSPDeclarations(Module &M) const override; |
125 | | |
126 | | /// getSetCCResultType - Return the ISD::SETCC ValueType |
127 | | EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, |
128 | | EVT VT) const override; |
129 | | |
130 | | SDValue |
131 | | LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
132 | | const SmallVectorImpl<ISD::InputArg> &Ins, |
133 | | const SDLoc &dl, SelectionDAG &DAG, |
134 | | SmallVectorImpl<SDValue> &InVals) const override; |
135 | | SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv, |
136 | | bool isVarArg, |
137 | | const SmallVectorImpl<ISD::InputArg> &Ins, |
138 | | const SDLoc &dl, SelectionDAG &DAG, |
139 | | SmallVectorImpl<SDValue> &InVals) const; |
140 | | SDValue LowerFormalArguments_64(SDValue Chain, CallingConv::ID CallConv, |
141 | | bool isVarArg, |
142 | | const SmallVectorImpl<ISD::InputArg> &Ins, |
143 | | const SDLoc &dl, SelectionDAG &DAG, |
144 | | SmallVectorImpl<SDValue> &InVals) const; |
145 | | |
146 | | SDValue |
147 | | LowerCall(TargetLowering::CallLoweringInfo &CLI, |
148 | | SmallVectorImpl<SDValue> &InVals) const override; |
149 | | SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI, |
150 | | SmallVectorImpl<SDValue> &InVals) const; |
151 | | SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, |
152 | | SmallVectorImpl<SDValue> &InVals) const; |
153 | | |
154 | | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
155 | | const SmallVectorImpl<ISD::OutputArg> &Outs, |
156 | | const SmallVectorImpl<SDValue> &OutVals, |
157 | | const SDLoc &dl, SelectionDAG &DAG) const override; |
158 | | SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv, |
159 | | bool IsVarArg, |
160 | | const SmallVectorImpl<ISD::OutputArg> &Outs, |
161 | | const SmallVectorImpl<SDValue> &OutVals, |
162 | | const SDLoc &DL, SelectionDAG &DAG) const; |
163 | | SDValue LowerReturn_64(SDValue Chain, CallingConv::ID CallConv, |
164 | | bool IsVarArg, |
165 | | const SmallVectorImpl<ISD::OutputArg> &Outs, |
166 | | const SmallVectorImpl<SDValue> &OutVals, |
167 | | const SDLoc &DL, SelectionDAG &DAG) const; |
168 | | |
169 | | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
170 | | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
171 | | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
172 | | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
173 | | |
174 | | SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG, |
175 | | const SparcTargetLowering &TLI) const ; |
176 | | SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG, |
177 | | const SparcTargetLowering &TLI) const ; |
178 | | |
179 | | unsigned getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const; |
180 | | SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; |
181 | | SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, |
182 | | SelectionDAG &DAG) const; |
183 | | SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; |
184 | | |
185 | | SDValue LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, |
186 | | const SDLoc &DL, SelectionDAG &DAG) const; |
187 | | SDValue LowerF128Op(SDValue Op, SelectionDAG &DAG, |
188 | | const char *LibFuncName, |
189 | | unsigned numArgs) const; |
190 | | SDValue LowerF128Compare(SDValue LHS, SDValue RHS, unsigned &SPCC, |
191 | | const SDLoc &DL, SelectionDAG &DAG) const; |
192 | | |
193 | | SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; |
194 | | |
195 | 8 | bool ShouldShrinkFPConstant(EVT VT) const override { |
196 | 8 | // Do not shrink FP constpool if VT == MVT::f128. |
197 | 8 | // (ldd, call _Q_fdtoq) is more expensive than two ldds. |
198 | 8 | return VT != MVT::f128; |
199 | 8 | } |
200 | | |
201 | 39 | bool shouldInsertFencesForAtomic(const Instruction *I) const override { |
202 | 39 | // FIXME: We insert fences for each atomics and generate |
203 | 39 | // sub-optimal code for PSO/TSO. (Approximately nobody uses any |
204 | 39 | // mode but TSO, which makes this even more silly) |
205 | 39 | return true; |
206 | 39 | } |
207 | | |
208 | | AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; |
209 | | |
210 | | void ReplaceNodeResults(SDNode *N, |
211 | | SmallVectorImpl<SDValue>& Results, |
212 | | SelectionDAG &DAG) const override; |
213 | | |
214 | | MachineBasicBlock *expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB, |
215 | | unsigned BROpcode) const; |
216 | | MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, |
217 | | MachineBasicBlock *MBB) const; |
218 | | MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, |
219 | | MachineBasicBlock *MBB) const; |
220 | | }; |
221 | | } // end namespace llvm |
222 | | |
223 | | #endif // SPARC_ISELLOWERING_H |