302 lines · c
1//===-- VEISelLowering.h - VE 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that VE uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H15#define LLVM_LIB_TARGET_VE_VEISELLOWERING_H16 17#include "VE.h"18#include "llvm/CodeGen/TargetLowering.h"19 20namespace llvm {21class VESubtarget;22 23/// Convert a DAG integer condition code to a VE ICC condition.24inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {25 switch (CC) {26 default:27 llvm_unreachable("Unknown integer condition code!");28 case ISD::SETEQ:29 return VECC::CC_IEQ;30 case ISD::SETNE:31 return VECC::CC_INE;32 case ISD::SETLT:33 return VECC::CC_IL;34 case ISD::SETGT:35 return VECC::CC_IG;36 case ISD::SETLE:37 return VECC::CC_ILE;38 case ISD::SETGE:39 return VECC::CC_IGE;40 case ISD::SETULT:41 return VECC::CC_IL;42 case ISD::SETULE:43 return VECC::CC_ILE;44 case ISD::SETUGT:45 return VECC::CC_IG;46 case ISD::SETUGE:47 return VECC::CC_IGE;48 }49}50 51/// Convert a DAG floating point condition code to a VE FCC condition.52inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) {53 switch (CC) {54 default:55 llvm_unreachable("Unknown fp condition code!");56 case ISD::SETFALSE:57 return VECC::CC_AF;58 case ISD::SETEQ:59 case ISD::SETOEQ:60 return VECC::CC_EQ;61 case ISD::SETNE:62 case ISD::SETONE:63 return VECC::CC_NE;64 case ISD::SETLT:65 case ISD::SETOLT:66 return VECC::CC_L;67 case ISD::SETGT:68 case ISD::SETOGT:69 return VECC::CC_G;70 case ISD::SETLE:71 case ISD::SETOLE:72 return VECC::CC_LE;73 case ISD::SETGE:74 case ISD::SETOGE:75 return VECC::CC_GE;76 case ISD::SETO:77 return VECC::CC_NUM;78 case ISD::SETUO:79 return VECC::CC_NAN;80 case ISD::SETUEQ:81 return VECC::CC_EQNAN;82 case ISD::SETUNE:83 return VECC::CC_NENAN;84 case ISD::SETULT:85 return VECC::CC_LNAN;86 case ISD::SETUGT:87 return VECC::CC_GNAN;88 case ISD::SETULE:89 return VECC::CC_LENAN;90 case ISD::SETUGE:91 return VECC::CC_GENAN;92 case ISD::SETTRUE:93 return VECC::CC_AT;94 }95}96 97/// getImmVal - get immediate representation of integer value98inline static uint64_t getImmVal(const ConstantSDNode *N) {99 return N->getSExtValue();100}101 102/// getFpImmVal - get immediate representation of floating point value103inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) {104 const APInt &Imm = N->getValueAPF().bitcastToAPInt();105 uint64_t Val = Imm.getZExtValue();106 if (Imm.getBitWidth() == 32) {107 // Immediate value of float place places at higher bits on VE.108 Val <<= 32;109 }110 return Val;111}112 113class VECustomDAG;114 115class VETargetLowering : public TargetLowering {116 const VESubtarget *Subtarget;117 118 void initRegisterClasses();119 void initSPUActions();120 void initVPUActions();121 122public:123 VETargetLowering(const TargetMachine &TM, const VESubtarget &STI);124 125 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {126 return MVT::i32;127 }128 129 Register getRegisterByName(const char *RegName, LLT VT,130 const MachineFunction &MF) const override;131 132 /// getSetCCResultType - Return the ISD::SETCC ValueType133 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,134 EVT VT) const override;135 136 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,137 bool isVarArg,138 const SmallVectorImpl<ISD::InputArg> &Ins,139 const SDLoc &dl, SelectionDAG &DAG,140 SmallVectorImpl<SDValue> &InVals) const override;141 142 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,143 SmallVectorImpl<SDValue> &InVals) const override;144 145 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,146 bool isVarArg,147 const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,148 LLVMContext &Context,149 const Type *RetTy) const override;150 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,151 const SmallVectorImpl<ISD::OutputArg> &Outs,152 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,153 SelectionDAG &DAG) const override;154 155 /// Helper functions for atomic operations.156 bool shouldInsertFencesForAtomic(const Instruction *I) const override {157 // VE uses release consistency, so need fence for each atomics.158 return true;159 }160 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,161 AtomicOrdering Ord) const override;162 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,163 AtomicOrdering Ord) const override;164 TargetLoweringBase::AtomicExpansionKind165 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;166 ISD::NodeType getExtendForAtomicOps() const override {167 return ISD::ANY_EXTEND;168 }169 170 /// Custom Lower {171 TargetLoweringBase::LegalizeAction172 getCustomOperationAction(SDNode &) const override;173 174 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;175 unsigned getJumpTableEncoding() const override;176 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,177 const MachineBasicBlock *MBB,178 unsigned Uid,179 MCContext &Ctx) const override;180 SDValue getPICJumpTableRelocBase(SDValue Table,181 SelectionDAG &DAG) const override;182 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only183 // EK_LabelDifference32.184 185 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;186 SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const;187 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;188 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;189 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;190 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;191 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;192 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;193 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;194 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;195 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;196 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;197 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;198 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;199 SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const;200 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;201 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;202 203 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;204 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;205 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;206 /// } Custom Lower207 208 /// Replace the results of node with an illegal result209 /// type with new values built out of custom code.210 ///211 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,212 SelectionDAG &DAG) const override;213 214 /// Custom Inserter {215 MachineBasicBlock *216 EmitInstrWithCustomInserter(MachineInstr &MI,217 MachineBasicBlock *MBB) const override;218 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,219 MachineBasicBlock *MBB) const;220 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,221 MachineBasicBlock *MBB) const;222 MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI,223 MachineBasicBlock *BB) const;224 225 void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,226 MachineBasicBlock *DispatchBB, int FI,227 int Offset) const;228 // Setup basic block address.229 Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,230 MachineBasicBlock *TargetBB, const DebugLoc &DL) const;231 // Prepare function/variable address.232 Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,233 StringRef Symbol, const DebugLoc &DL, bool IsLocal,234 bool IsCall) const;235 /// } Custom Inserter236 237 /// VVP Lowering {238 SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const;239 SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const;240 SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const;241 242 SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const;243 SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const;244 SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const;245 SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const;246 SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const;247 SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const;248 /// } VVPLowering249 250 /// Custom DAGCombine {251 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;252 253 SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const;254 SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const;255 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;256 /// } Custom DAGCombine257 258 SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;259 SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,260 SelectionDAG &DAG) const;261 SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;262 263 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;264 bool isFPImmLegal(const APFloat &Imm, EVT VT,265 bool ForCodeSize) const override;266 /// Returns true if the target allows unaligned memory accesses of the267 /// specified type.268 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A,269 MachineMemOperand::Flags Flags,270 unsigned *Fast) const override;271 272 /// Inline Assembly {273 274 ConstraintType getConstraintType(StringRef Constraint) const override;275 std::pair<unsigned, const TargetRegisterClass *>276 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,277 StringRef Constraint, MVT VT) const override;278 279 /// } Inline Assembly280 281 /// Target Optimization {282 283 // Return lower limit for number of blocks in a jump table.284 unsigned getMinimumJumpTableEntries() const override;285 286 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply.287 bool isIntDivCheap(EVT, AttributeList) const override { return false; }288 // VE doesn't have rem.289 bool hasStandaloneRem(EVT) const override { return false; }290 // VE LDZ instruction returns 64 if the input is zero.291 bool isCheapToSpeculateCtlz(Type *) const override { return true; }292 // VE LDZ instruction is fast.293 bool isCtlzFast() const override { return true; }294 // VE has NND instruction.295 bool hasAndNot(SDValue Y) const override;296 297 /// } Target Optimization298};299} // namespace llvm300 301#endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H302