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