1 //===-- VEISelLowering.h - VE DAG Lowering Interface ------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the interfaces that VE uses to lower LLVM code into a
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H
15 #define LLVM_LIB_TARGET_VE_VEISELLOWERING_H
18 #include "llvm/CodeGen/TargetLowering.h"
24 enum NodeType
: unsigned {
25 FIRST_NUMBER
= ISD::BUILTIN_OP_END
,
27 CMPI
, // Compare between two signed integer values.
28 CMPU
, // Compare between two unsigned integer values.
29 CMPF
, // Compare between two floating-point values.
30 CMPQ
, // Compare between two quad floating-point values.
31 CMOV
, // Select between two values using the result of comparison.
33 CALL
, // A call instruction.
34 EH_SJLJ_LONGJMP
, // SjLj exception handling longjmp.
35 EH_SJLJ_SETJMP
, // SjLj exception handling setjmp.
36 EH_SJLJ_SETUP_DISPATCH
, // SjLj exception handling setup_dispatch.
37 GETFUNPLT
, // Load function address through %plt insturction.
38 GETTLSADDR
, // Load address for TLS access.
39 GETSTACKTOP
, // Retrieve address of stack top (first address of
40 // locals and temporaries).
41 GLOBAL_BASE_REG
, // Global base reg for PIC.
42 Hi
, // Hi/Lo operations, typically on a global address.
43 Lo
, // Hi/Lo operations, typically on a global address.
44 RET_GLUE
, // Return with a flag operand.
45 TS1AM
, // A TS1AM instruction used for 1/2 bytes swap.
46 VEC_UNPACK_LO
, // unpack the lo v256 slice of a packed v512 vector.
47 VEC_UNPACK_HI
, // unpack the hi v256 slice of a packed v512 vector.
48 // 0: v512 vector, 1: AVL
49 VEC_PACK
, // pack a lo and a hi vector into one v512 vector
50 // 0: v256 lo vector, 1: v256 hi vector, 2: AVL
52 VEC_BROADCAST
, // A vector broadcast instruction.
53 // 0: scalar value, 1: VL
55 REPL_F32
, // Replicate subregister to other half.
57 // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of
58 // data, whereas the raw EVL coming in from VP nodes always refers to number
59 // of elements, regardless of their size.
63 #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
64 #include "VVPNodes.def"
68 /// Convert a DAG integer condition code to a VE ICC condition.
69 inline static VECC::CondCode
intCondCode2Icc(ISD::CondCode CC
) {
72 llvm_unreachable("Unknown integer condition code!");
96 /// Convert a DAG floating point condition code to a VE FCC condition.
97 inline static VECC::CondCode
fpCondCode2Fcc(ISD::CondCode CC
) {
100 llvm_unreachable("Unknown fp condition code!");
126 return VECC::CC_EQNAN
;
128 return VECC::CC_NENAN
;
130 return VECC::CC_LNAN
;
132 return VECC::CC_GNAN
;
134 return VECC::CC_LENAN
;
136 return VECC::CC_GENAN
;
142 /// getImmVal - get immediate representation of integer value
143 inline static uint64_t getImmVal(const ConstantSDNode
*N
) {
144 return N
->getSExtValue();
147 /// getFpImmVal - get immediate representation of floating point value
148 inline static uint64_t getFpImmVal(const ConstantFPSDNode
*N
) {
149 const APInt
&Imm
= N
->getValueAPF().bitcastToAPInt();
150 uint64_t Val
= Imm
.getZExtValue();
151 if (Imm
.getBitWidth() == 32) {
152 // Immediate value of float place places at higher bits on VE.
160 class VETargetLowering
: public TargetLowering
{
161 const VESubtarget
*Subtarget
;
163 void initRegisterClasses();
164 void initSPUActions();
165 void initVPUActions();
168 VETargetLowering(const TargetMachine
&TM
, const VESubtarget
&STI
);
170 const char *getTargetNodeName(unsigned Opcode
) const override
;
171 MVT
getScalarShiftAmountTy(const DataLayout
&, EVT
) const override
{
175 Register
getRegisterByName(const char *RegName
, LLT VT
,
176 const MachineFunction
&MF
) const override
;
178 /// getSetCCResultType - Return the ISD::SETCC ValueType
179 EVT
getSetCCResultType(const DataLayout
&DL
, LLVMContext
&Context
,
180 EVT VT
) const override
;
182 SDValue
LowerFormalArguments(SDValue Chain
, CallingConv::ID CallConv
,
184 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
185 const SDLoc
&dl
, SelectionDAG
&DAG
,
186 SmallVectorImpl
<SDValue
> &InVals
) const override
;
188 SDValue
LowerCall(TargetLowering::CallLoweringInfo
&CLI
,
189 SmallVectorImpl
<SDValue
> &InVals
) const override
;
191 bool CanLowerReturn(CallingConv::ID CallConv
, MachineFunction
&MF
,
193 const SmallVectorImpl
<ISD::OutputArg
> &ArgsFlags
,
194 LLVMContext
&Context
,
195 const Type
*RetTy
) const override
;
196 SDValue
LowerReturn(SDValue Chain
, CallingConv::ID CallConv
, bool isVarArg
,
197 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
198 const SmallVectorImpl
<SDValue
> &OutVals
, const SDLoc
&dl
,
199 SelectionDAG
&DAG
) const override
;
201 /// Helper functions for atomic operations.
202 bool shouldInsertFencesForAtomic(const Instruction
*I
) const override
{
203 // VE uses release consistency, so need fence for each atomics.
206 Instruction
*emitLeadingFence(IRBuilderBase
&Builder
, Instruction
*Inst
,
207 AtomicOrdering Ord
) const override
;
208 Instruction
*emitTrailingFence(IRBuilderBase
&Builder
, Instruction
*Inst
,
209 AtomicOrdering Ord
) const override
;
210 TargetLoweringBase::AtomicExpansionKind
211 shouldExpandAtomicRMWInIR(AtomicRMWInst
*AI
) const override
;
212 ISD::NodeType
getExtendForAtomicOps() const override
{
213 return ISD::ANY_EXTEND
;
217 TargetLoweringBase::LegalizeAction
218 getCustomOperationAction(SDNode
&) const override
;
220 SDValue
LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const override
;
221 unsigned getJumpTableEncoding() const override
;
222 const MCExpr
*LowerCustomJumpTableEntry(const MachineJumpTableInfo
*MJTI
,
223 const MachineBasicBlock
*MBB
,
225 MCContext
&Ctx
) const override
;
226 SDValue
getPICJumpTableRelocBase(SDValue Table
,
227 SelectionDAG
&DAG
) const override
;
228 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only
229 // EK_LabelDifference32.
231 SDValue
lowerATOMIC_FENCE(SDValue Op
, SelectionDAG
&DAG
) const;
232 SDValue
lowerATOMIC_SWAP(SDValue Op
, SelectionDAG
&DAG
) const;
233 SDValue
lowerBlockAddress(SDValue Op
, SelectionDAG
&DAG
) const;
234 SDValue
lowerConstantPool(SDValue Op
, SelectionDAG
&DAG
) const;
235 SDValue
lowerDYNAMIC_STACKALLOC(SDValue Op
, SelectionDAG
&DAG
) const;
236 SDValue
lowerEH_SJLJ_LONGJMP(SDValue Op
, SelectionDAG
&DAG
) const;
237 SDValue
lowerEH_SJLJ_SETJMP(SDValue Op
, SelectionDAG
&DAG
) const;
238 SDValue
lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op
, SelectionDAG
&DAG
) const;
239 SDValue
lowerGlobalAddress(SDValue Op
, SelectionDAG
&DAG
) const;
240 SDValue
lowerGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
241 SDValue
lowerINTRINSIC_WO_CHAIN(SDValue Op
, SelectionDAG
&DAG
) const;
242 SDValue
lowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) const;
243 SDValue
lowerLOAD(SDValue Op
, SelectionDAG
&DAG
) const;
244 SDValue
lowerSTORE(SDValue Op
, SelectionDAG
&DAG
) const;
245 SDValue
lowerToTLSGeneralDynamicModel(SDValue Op
, SelectionDAG
&DAG
) const;
246 SDValue
lowerVASTART(SDValue Op
, SelectionDAG
&DAG
) const;
247 SDValue
lowerVAARG(SDValue Op
, SelectionDAG
&DAG
) const;
249 SDValue
lowerBUILD_VECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
250 SDValue
lowerEXTRACT_VECTOR_ELT(SDValue Op
, SelectionDAG
&DAG
) const;
251 SDValue
lowerINSERT_VECTOR_ELT(SDValue Op
, SelectionDAG
&DAG
) const;
254 /// Replace the results of node with an illegal result
255 /// type with new values built out of custom code.
257 void ReplaceNodeResults(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
258 SelectionDAG
&DAG
) const override
;
260 /// Custom Inserter {
262 EmitInstrWithCustomInserter(MachineInstr
&MI
,
263 MachineBasicBlock
*MBB
) const override
;
264 MachineBasicBlock
*emitEHSjLjLongJmp(MachineInstr
&MI
,
265 MachineBasicBlock
*MBB
) const;
266 MachineBasicBlock
*emitEHSjLjSetJmp(MachineInstr
&MI
,
267 MachineBasicBlock
*MBB
) const;
268 MachineBasicBlock
*emitSjLjDispatchBlock(MachineInstr
&MI
,
269 MachineBasicBlock
*BB
) const;
271 void setupEntryBlockForSjLj(MachineInstr
&MI
, MachineBasicBlock
*MBB
,
272 MachineBasicBlock
*DispatchBB
, int FI
,
274 // Setup basic block address.
275 Register
prepareMBB(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
276 MachineBasicBlock
*TargetBB
, const DebugLoc
&DL
) const;
277 // Prepare function/variable address.
278 Register
prepareSymbol(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
279 StringRef Symbol
, const DebugLoc
&DL
, bool IsLocal
,
281 /// } Custom Inserter
284 SDValue
lowerToVVP(SDValue Op
, SelectionDAG
&DAG
) const;
285 SDValue
lowerVVP_LOAD_STORE(SDValue Op
, VECustomDAG
&) const;
286 SDValue
lowerVVP_GATHER_SCATTER(SDValue Op
, VECustomDAG
&) const;
288 SDValue
legalizeInternalVectorOp(SDValue Op
, SelectionDAG
&DAG
) const;
289 SDValue
legalizeInternalLoadStoreOp(SDValue Op
, VECustomDAG
&CDAG
) const;
290 SDValue
splitVectorOp(SDValue Op
, VECustomDAG
&CDAG
) const;
291 SDValue
splitPackedLoadStore(SDValue Op
, VECustomDAG
&CDAG
) const;
292 SDValue
legalizePackedAVL(SDValue Op
, VECustomDAG
&CDAG
) const;
293 SDValue
splitMaskArithmetic(SDValue Op
, SelectionDAG
&DAG
) const;
296 /// Custom DAGCombine {
297 SDValue
PerformDAGCombine(SDNode
*N
, DAGCombinerInfo
&DCI
) const override
;
299 SDValue
combineSelect(SDNode
*N
, DAGCombinerInfo
&DCI
) const;
300 SDValue
combineSelectCC(SDNode
*N
, DAGCombinerInfo
&DCI
) const;
301 SDValue
combineTRUNCATE(SDNode
*N
, DAGCombinerInfo
&DCI
) const;
302 /// } Custom DAGCombine
304 SDValue
withTargetFlags(SDValue Op
, unsigned TF
, SelectionDAG
&DAG
) const;
305 SDValue
makeHiLoPair(SDValue Op
, unsigned HiTF
, unsigned LoTF
,
306 SelectionDAG
&DAG
) const;
307 SDValue
makeAddress(SDValue Op
, SelectionDAG
&DAG
) const;
309 bool isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const override
;
310 bool isFPImmLegal(const APFloat
&Imm
, EVT VT
,
311 bool ForCodeSize
) const override
;
312 /// Returns true if the target allows unaligned memory accesses of the
314 bool allowsMisalignedMemoryAccesses(EVT VT
, unsigned AS
, Align A
,
315 MachineMemOperand::Flags Flags
,
316 unsigned *Fast
) const override
;
318 /// Inline Assembly {
320 ConstraintType
getConstraintType(StringRef Constraint
) const override
;
321 std::pair
<unsigned, const TargetRegisterClass
*>
322 getRegForInlineAsmConstraint(const TargetRegisterInfo
*TRI
,
323 StringRef Constraint
, MVT VT
) const override
;
325 /// } Inline Assembly
327 /// Target Optimization {
329 // Return lower limit for number of blocks in a jump table.
330 unsigned getMinimumJumpTableEntries() const override
;
332 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply.
333 bool isIntDivCheap(EVT
, AttributeList
) const override
{ return false; }
334 // VE doesn't have rem.
335 bool hasStandaloneRem(EVT
) const override
{ return false; }
336 // VE LDZ instruction returns 64 if the input is zero.
337 bool isCheapToSpeculateCtlz(Type
*) const override
{ return true; }
338 // VE LDZ instruction is fast.
339 bool isCtlzFast() const override
{ return true; }
340 // VE has NND instruction.
341 bool hasAndNot(SDValue Y
) const override
;
343 /// } Target Optimization
347 #endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H