1480093f4SDimitry Andric //===-- VEISelLowering.h - VE DAG Lowering Interface ------------*- C++ -*-===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file defines the interfaces that VE uses to lower LLVM code into a 10480093f4SDimitry Andric // selection DAG. 11480093f4SDimitry Andric // 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 14480093f4SDimitry Andric #ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H 15480093f4SDimitry Andric #define LLVM_LIB_TARGET_VE_VEISELLOWERING_H 16480093f4SDimitry Andric 17480093f4SDimitry Andric #include "VE.h" 18480093f4SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 19480093f4SDimitry Andric 20480093f4SDimitry Andric namespace llvm { 21480093f4SDimitry Andric class VESubtarget; 22480093f4SDimitry Andric 23480093f4SDimitry Andric namespace VEISD { 24480093f4SDimitry Andric enum NodeType : unsigned { 25480093f4SDimitry Andric FIRST_NUMBER = ISD::BUILTIN_OP_END, 265ffd83dbSDimitry Andric 27bdd1243dSDimitry Andric CMPI, // Compare between two signed integer values. 28bdd1243dSDimitry Andric CMPU, // Compare between two unsigned integer values. 29bdd1243dSDimitry Andric CMPF, // Compare between two floating-point values. 30bdd1243dSDimitry Andric CMPQ, // Compare between two quad floating-point values. 31bdd1243dSDimitry Andric CMOV, // Select between two values using the result of comparison. 32bdd1243dSDimitry Andric 335ffd83dbSDimitry Andric CALL, // A call instruction. 34e8d8bef9SDimitry Andric EH_SJLJ_LONGJMP, // SjLj exception handling longjmp. 35e8d8bef9SDimitry Andric EH_SJLJ_SETJMP, // SjLj exception handling setjmp. 36e8d8bef9SDimitry Andric EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch. 37e8d8bef9SDimitry Andric GETFUNPLT, // Load function address through %plt insturction. 38e8d8bef9SDimitry Andric GETTLSADDR, // Load address for TLS access. 39e8d8bef9SDimitry Andric GETSTACKTOP, // Retrieve address of stack top (first address of 40e8d8bef9SDimitry Andric // locals and temporaries). 415ffd83dbSDimitry Andric GLOBAL_BASE_REG, // Global base reg for PIC. 42e8d8bef9SDimitry Andric Hi, // Hi/Lo operations, typically on a global address. 43e8d8bef9SDimitry Andric Lo, // Hi/Lo operations, typically on a global address. 4406c3fb27SDimitry Andric RET_GLUE, // Return with a flag operand. 45e8d8bef9SDimitry Andric TS1AM, // A TS1AM instruction used for 1/2 bytes swap. 4681ad6265SDimitry Andric VEC_UNPACK_LO, // unpack the lo v256 slice of a packed v512 vector. 4781ad6265SDimitry Andric VEC_UNPACK_HI, // unpack the hi v256 slice of a packed v512 vector. 4881ad6265SDimitry Andric // 0: v512 vector, 1: AVL 4981ad6265SDimitry Andric VEC_PACK, // pack a lo and a hi vector into one v512 vector 5081ad6265SDimitry Andric // 0: v256 lo vector, 1: v256 hi vector, 2: AVL 5181ad6265SDimitry Andric 52e8d8bef9SDimitry Andric VEC_BROADCAST, // A vector broadcast instruction. 53e8d8bef9SDimitry Andric // 0: scalar value, 1: VL 5404eeddc0SDimitry Andric REPL_I32, 5504eeddc0SDimitry Andric REPL_F32, // Replicate subregister to other half. 56e8d8bef9SDimitry Andric 5781ad6265SDimitry Andric // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of 5881ad6265SDimitry Andric // data, whereas the raw EVL coming in from VP nodes always refers to number 5981ad6265SDimitry Andric // of elements, regardless of their size. 6081ad6265SDimitry Andric LEGALAVL, 6181ad6265SDimitry Andric 62e8d8bef9SDimitry Andric // VVP_* nodes. 63e8d8bef9SDimitry Andric #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME, 64e8d8bef9SDimitry Andric #include "VVPNodes.def" 65480093f4SDimitry Andric }; 66480093f4SDimitry Andric } 67480093f4SDimitry Andric 68*5f757f3fSDimitry Andric /// Convert a DAG integer condition code to a VE ICC condition. 69*5f757f3fSDimitry Andric inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) { 70*5f757f3fSDimitry Andric switch (CC) { 71*5f757f3fSDimitry Andric default: 72*5f757f3fSDimitry Andric llvm_unreachable("Unknown integer condition code!"); 73*5f757f3fSDimitry Andric case ISD::SETEQ: 74*5f757f3fSDimitry Andric return VECC::CC_IEQ; 75*5f757f3fSDimitry Andric case ISD::SETNE: 76*5f757f3fSDimitry Andric return VECC::CC_INE; 77*5f757f3fSDimitry Andric case ISD::SETLT: 78*5f757f3fSDimitry Andric return VECC::CC_IL; 79*5f757f3fSDimitry Andric case ISD::SETGT: 80*5f757f3fSDimitry Andric return VECC::CC_IG; 81*5f757f3fSDimitry Andric case ISD::SETLE: 82*5f757f3fSDimitry Andric return VECC::CC_ILE; 83*5f757f3fSDimitry Andric case ISD::SETGE: 84*5f757f3fSDimitry Andric return VECC::CC_IGE; 85*5f757f3fSDimitry Andric case ISD::SETULT: 86*5f757f3fSDimitry Andric return VECC::CC_IL; 87*5f757f3fSDimitry Andric case ISD::SETULE: 88*5f757f3fSDimitry Andric return VECC::CC_ILE; 89*5f757f3fSDimitry Andric case ISD::SETUGT: 90*5f757f3fSDimitry Andric return VECC::CC_IG; 91*5f757f3fSDimitry Andric case ISD::SETUGE: 92*5f757f3fSDimitry Andric return VECC::CC_IGE; 93*5f757f3fSDimitry Andric } 94*5f757f3fSDimitry Andric } 95*5f757f3fSDimitry Andric 96*5f757f3fSDimitry Andric /// Convert a DAG floating point condition code to a VE FCC condition. 97*5f757f3fSDimitry Andric inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) { 98*5f757f3fSDimitry Andric switch (CC) { 99*5f757f3fSDimitry Andric default: 100*5f757f3fSDimitry Andric llvm_unreachable("Unknown fp condition code!"); 101*5f757f3fSDimitry Andric case ISD::SETFALSE: 102*5f757f3fSDimitry Andric return VECC::CC_AF; 103*5f757f3fSDimitry Andric case ISD::SETEQ: 104*5f757f3fSDimitry Andric case ISD::SETOEQ: 105*5f757f3fSDimitry Andric return VECC::CC_EQ; 106*5f757f3fSDimitry Andric case ISD::SETNE: 107*5f757f3fSDimitry Andric case ISD::SETONE: 108*5f757f3fSDimitry Andric return VECC::CC_NE; 109*5f757f3fSDimitry Andric case ISD::SETLT: 110*5f757f3fSDimitry Andric case ISD::SETOLT: 111*5f757f3fSDimitry Andric return VECC::CC_L; 112*5f757f3fSDimitry Andric case ISD::SETGT: 113*5f757f3fSDimitry Andric case ISD::SETOGT: 114*5f757f3fSDimitry Andric return VECC::CC_G; 115*5f757f3fSDimitry Andric case ISD::SETLE: 116*5f757f3fSDimitry Andric case ISD::SETOLE: 117*5f757f3fSDimitry Andric return VECC::CC_LE; 118*5f757f3fSDimitry Andric case ISD::SETGE: 119*5f757f3fSDimitry Andric case ISD::SETOGE: 120*5f757f3fSDimitry Andric return VECC::CC_GE; 121*5f757f3fSDimitry Andric case ISD::SETO: 122*5f757f3fSDimitry Andric return VECC::CC_NUM; 123*5f757f3fSDimitry Andric case ISD::SETUO: 124*5f757f3fSDimitry Andric return VECC::CC_NAN; 125*5f757f3fSDimitry Andric case ISD::SETUEQ: 126*5f757f3fSDimitry Andric return VECC::CC_EQNAN; 127*5f757f3fSDimitry Andric case ISD::SETUNE: 128*5f757f3fSDimitry Andric return VECC::CC_NENAN; 129*5f757f3fSDimitry Andric case ISD::SETULT: 130*5f757f3fSDimitry Andric return VECC::CC_LNAN; 131*5f757f3fSDimitry Andric case ISD::SETUGT: 132*5f757f3fSDimitry Andric return VECC::CC_GNAN; 133*5f757f3fSDimitry Andric case ISD::SETULE: 134*5f757f3fSDimitry Andric return VECC::CC_LENAN; 135*5f757f3fSDimitry Andric case ISD::SETUGE: 136*5f757f3fSDimitry Andric return VECC::CC_GENAN; 137*5f757f3fSDimitry Andric case ISD::SETTRUE: 138*5f757f3fSDimitry Andric return VECC::CC_AT; 139*5f757f3fSDimitry Andric } 140*5f757f3fSDimitry Andric } 141*5f757f3fSDimitry Andric 142*5f757f3fSDimitry Andric /// getImmVal - get immediate representation of integer value 143*5f757f3fSDimitry Andric inline static uint64_t getImmVal(const ConstantSDNode *N) { 144*5f757f3fSDimitry Andric return N->getSExtValue(); 145*5f757f3fSDimitry Andric } 146*5f757f3fSDimitry Andric 147*5f757f3fSDimitry Andric /// getFpImmVal - get immediate representation of floating point value 148*5f757f3fSDimitry Andric inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) { 149*5f757f3fSDimitry Andric const APInt &Imm = N->getValueAPF().bitcastToAPInt(); 150*5f757f3fSDimitry Andric uint64_t Val = Imm.getZExtValue(); 151*5f757f3fSDimitry Andric if (Imm.getBitWidth() == 32) { 152*5f757f3fSDimitry Andric // Immediate value of float place places at higher bits on VE. 153*5f757f3fSDimitry Andric Val <<= 32; 154*5f757f3fSDimitry Andric } 155*5f757f3fSDimitry Andric return Val; 156*5f757f3fSDimitry Andric } 157*5f757f3fSDimitry Andric 15881ad6265SDimitry Andric class VECustomDAG; 15981ad6265SDimitry Andric 160480093f4SDimitry Andric class VETargetLowering : public TargetLowering { 161480093f4SDimitry Andric const VESubtarget *Subtarget; 162480093f4SDimitry Andric 163e8d8bef9SDimitry Andric void initRegisterClasses(); 164e8d8bef9SDimitry Andric void initSPUActions(); 165e8d8bef9SDimitry Andric void initVPUActions(); 166e8d8bef9SDimitry Andric 167480093f4SDimitry Andric public: 168480093f4SDimitry Andric VETargetLowering(const TargetMachine &TM, const VESubtarget &STI); 169480093f4SDimitry Andric 170480093f4SDimitry Andric const char *getTargetNodeName(unsigned Opcode) const override; 1715ffd83dbSDimitry Andric MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 1725ffd83dbSDimitry Andric return MVT::i32; 1735ffd83dbSDimitry Andric } 174480093f4SDimitry Andric 175480093f4SDimitry Andric Register getRegisterByName(const char *RegName, LLT VT, 176480093f4SDimitry Andric const MachineFunction &MF) const override; 177480093f4SDimitry Andric 178480093f4SDimitry Andric /// getSetCCResultType - Return the ISD::SETCC ValueType 179480093f4SDimitry Andric EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 180480093f4SDimitry Andric EVT VT) const override; 181480093f4SDimitry Andric 182480093f4SDimitry Andric SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 183480093f4SDimitry Andric bool isVarArg, 184480093f4SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 185480093f4SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 186480093f4SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 187480093f4SDimitry Andric 1885ffd83dbSDimitry Andric SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 1895ffd83dbSDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1905ffd83dbSDimitry Andric 191480093f4SDimitry Andric bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 192480093f4SDimitry Andric bool isVarArg, 193480093f4SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 194480093f4SDimitry Andric LLVMContext &Context) const override; 195480093f4SDimitry Andric SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 196480093f4SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 197480093f4SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 198480093f4SDimitry Andric SelectionDAG &DAG) const override; 1995ffd83dbSDimitry Andric 200e8d8bef9SDimitry Andric /// Helper functions for atomic operations. 201e8d8bef9SDimitry Andric bool shouldInsertFencesForAtomic(const Instruction *I) const override { 202e8d8bef9SDimitry Andric // VE uses release consistency, so need fence for each atomics. 203e8d8bef9SDimitry Andric return true; 204e8d8bef9SDimitry Andric } 205fe6060f1SDimitry Andric Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 206e8d8bef9SDimitry Andric AtomicOrdering Ord) const override; 207fe6060f1SDimitry Andric Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 208e8d8bef9SDimitry Andric AtomicOrdering Ord) const override; 209e8d8bef9SDimitry Andric TargetLoweringBase::AtomicExpansionKind 210e8d8bef9SDimitry Andric shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 211fe6060f1SDimitry Andric ISD::NodeType getExtendForAtomicOps() const override { 212fe6060f1SDimitry Andric return ISD::ANY_EXTEND; 213fe6060f1SDimitry Andric } 214e8d8bef9SDimitry Andric 2155ffd83dbSDimitry Andric /// Custom Lower { 21681ad6265SDimitry Andric TargetLoweringBase::LegalizeAction 21781ad6265SDimitry Andric getCustomOperationAction(SDNode &) const override; 21881ad6265SDimitry Andric 2195ffd83dbSDimitry Andric SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 220e8d8bef9SDimitry Andric unsigned getJumpTableEncoding() const override; 221e8d8bef9SDimitry Andric const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 222e8d8bef9SDimitry Andric const MachineBasicBlock *MBB, 223e8d8bef9SDimitry Andric unsigned Uid, 224e8d8bef9SDimitry Andric MCContext &Ctx) const override; 225e8d8bef9SDimitry Andric SDValue getPICJumpTableRelocBase(SDValue Table, 226e8d8bef9SDimitry Andric SelectionDAG &DAG) const override; 227e8d8bef9SDimitry Andric // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only 228e8d8bef9SDimitry Andric // EK_LabelDifference32. 2295ffd83dbSDimitry Andric 230e8d8bef9SDimitry Andric SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 231e8d8bef9SDimitry Andric SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const; 232e8d8bef9SDimitry Andric SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 233e8d8bef9SDimitry Andric SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 2345ffd83dbSDimitry Andric SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 235e8d8bef9SDimitry Andric SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 236e8d8bef9SDimitry Andric SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 237e8d8bef9SDimitry Andric SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; 238e8d8bef9SDimitry Andric SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 239e8d8bef9SDimitry Andric SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 240e8d8bef9SDimitry Andric SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 241e8d8bef9SDimitry Andric SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 242e8d8bef9SDimitry Andric SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 243e8d8bef9SDimitry Andric SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 244e8d8bef9SDimitry Andric SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const; 245e8d8bef9SDimitry Andric SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 246e8d8bef9SDimitry Andric SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; 247e8d8bef9SDimitry Andric 248e8d8bef9SDimitry Andric SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 249e8d8bef9SDimitry Andric SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 250e8d8bef9SDimitry Andric SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 2515ffd83dbSDimitry Andric /// } Custom Lower 2525ffd83dbSDimitry Andric 253e8d8bef9SDimitry Andric /// Replace the results of node with an illegal result 254e8d8bef9SDimitry Andric /// type with new values built out of custom code. 255e8d8bef9SDimitry Andric /// 256e8d8bef9SDimitry Andric void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 257e8d8bef9SDimitry Andric SelectionDAG &DAG) const override; 258e8d8bef9SDimitry Andric 259e8d8bef9SDimitry Andric /// Custom Inserter { 260e8d8bef9SDimitry Andric MachineBasicBlock * 261e8d8bef9SDimitry Andric EmitInstrWithCustomInserter(MachineInstr &MI, 262e8d8bef9SDimitry Andric MachineBasicBlock *MBB) const override; 263e8d8bef9SDimitry Andric MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 264e8d8bef9SDimitry Andric MachineBasicBlock *MBB) const; 265e8d8bef9SDimitry Andric MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 266e8d8bef9SDimitry Andric MachineBasicBlock *MBB) const; 267e8d8bef9SDimitry Andric MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI, 268e8d8bef9SDimitry Andric MachineBasicBlock *BB) const; 269e8d8bef9SDimitry Andric 270e8d8bef9SDimitry Andric void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, 271e8d8bef9SDimitry Andric MachineBasicBlock *DispatchBB, int FI, 272e8d8bef9SDimitry Andric int Offset) const; 273e8d8bef9SDimitry Andric // Setup basic block address. 274e8d8bef9SDimitry Andric Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 275e8d8bef9SDimitry Andric MachineBasicBlock *TargetBB, const DebugLoc &DL) const; 276e8d8bef9SDimitry Andric // Prepare function/variable address. 277e8d8bef9SDimitry Andric Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 278e8d8bef9SDimitry Andric StringRef Symbol, const DebugLoc &DL, bool IsLocal, 279e8d8bef9SDimitry Andric bool IsCall) const; 280e8d8bef9SDimitry Andric /// } Custom Inserter 281e8d8bef9SDimitry Andric 282e8d8bef9SDimitry Andric /// VVP Lowering { 283e8d8bef9SDimitry Andric SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const; 28481ad6265SDimitry Andric SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const; 28581ad6265SDimitry Andric SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const; 28681ad6265SDimitry Andric 28781ad6265SDimitry Andric SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const; 28881ad6265SDimitry Andric SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const; 28981ad6265SDimitry Andric SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const; 29081ad6265SDimitry Andric SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const; 29181ad6265SDimitry Andric SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const; 29281ad6265SDimitry Andric SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const; 293e8d8bef9SDimitry Andric /// } VVPLowering 294e8d8bef9SDimitry Andric 295e8d8bef9SDimitry Andric /// Custom DAGCombine { 296e8d8bef9SDimitry Andric SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 297e8d8bef9SDimitry Andric 298bdd1243dSDimitry Andric SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const; 299bdd1243dSDimitry Andric SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const; 300e8d8bef9SDimitry Andric SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 301e8d8bef9SDimitry Andric /// } Custom DAGCombine 302e8d8bef9SDimitry Andric 3035ffd83dbSDimitry Andric SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 3045ffd83dbSDimitry Andric SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 3055ffd83dbSDimitry Andric SelectionDAG &DAG) const; 3065ffd83dbSDimitry Andric SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 3075ffd83dbSDimitry Andric 308e8d8bef9SDimitry Andric bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 3095ffd83dbSDimitry Andric bool isFPImmLegal(const APFloat &Imm, EVT VT, 3105ffd83dbSDimitry Andric bool ForCodeSize) const override; 3115ffd83dbSDimitry Andric /// Returns true if the target allows unaligned memory accesses of the 3125ffd83dbSDimitry Andric /// specified type. 313fe6060f1SDimitry Andric bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, 3145ffd83dbSDimitry Andric MachineMemOperand::Flags Flags, 315bdd1243dSDimitry Andric unsigned *Fast) const override; 3165ffd83dbSDimitry Andric 317e8d8bef9SDimitry Andric /// Inline Assembly { 3185ffd83dbSDimitry Andric 319e8d8bef9SDimitry Andric ConstraintType getConstraintType(StringRef Constraint) const override; 320e8d8bef9SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> 321e8d8bef9SDimitry Andric getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 322e8d8bef9SDimitry Andric StringRef Constraint, MVT VT) const override; 323e8d8bef9SDimitry Andric 324e8d8bef9SDimitry Andric /// } Inline Assembly 325e8d8bef9SDimitry Andric 326e8d8bef9SDimitry Andric /// Target Optimization { 327e8d8bef9SDimitry Andric 328e8d8bef9SDimitry Andric // Return lower limit for number of blocks in a jump table. 329e8d8bef9SDimitry Andric unsigned getMinimumJumpTableEntries() const override; 330e8d8bef9SDimitry Andric 331e8d8bef9SDimitry Andric // SX-Aurora VE's s/udiv is 5-9 times slower than multiply. 332e8d8bef9SDimitry Andric bool isIntDivCheap(EVT, AttributeList) const override { return false; } 333e8d8bef9SDimitry Andric // VE doesn't have rem. 334e8d8bef9SDimitry Andric bool hasStandaloneRem(EVT) const override { return false; } 335e8d8bef9SDimitry Andric // VE LDZ instruction returns 64 if the input is zero. 336bdd1243dSDimitry Andric bool isCheapToSpeculateCtlz(Type *) const override { return true; } 337e8d8bef9SDimitry Andric // VE LDZ instruction is fast. 338e8d8bef9SDimitry Andric bool isCtlzFast() const override { return true; } 339e8d8bef9SDimitry Andric // VE has NND instruction. 3405ffd83dbSDimitry Andric bool hasAndNot(SDValue Y) const override; 341e8d8bef9SDimitry Andric 342e8d8bef9SDimitry Andric /// } Target Optimization 343480093f4SDimitry Andric }; 344480093f4SDimitry Andric } // namespace llvm 345480093f4SDimitry Andric 34604eeddc0SDimitry Andric #endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H 347