1480093f4SDimitry Andric //===-- VEISelDAGToDAG.cpp - A dag to dag inst selector for VE ------------===// 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 an instruction selector for the VE target. 10480093f4SDimitry Andric // 11480093f4SDimitry Andric //===----------------------------------------------------------------------===// 12480093f4SDimitry Andric 13*81ad6265SDimitry Andric #include "VE.h" 14480093f4SDimitry Andric #include "VETargetMachine.h" 15480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 16480093f4SDimitry Andric #include "llvm/CodeGen/SelectionDAGISel.h" 17480093f4SDimitry Andric #include "llvm/IR/Intrinsics.h" 18480093f4SDimitry Andric #include "llvm/Support/Debug.h" 19480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 20480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h" 21480093f4SDimitry Andric using namespace llvm; 22480093f4SDimitry Andric 23480093f4SDimitry Andric //===----------------------------------------------------------------------===// 24480093f4SDimitry Andric // Instruction Selector Implementation 25480093f4SDimitry Andric //===----------------------------------------------------------------------===// 26480093f4SDimitry Andric 275ffd83dbSDimitry Andric /// Convert a DAG integer condition code to a VE ICC condition. 285ffd83dbSDimitry Andric inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) { 295ffd83dbSDimitry Andric switch (CC) { 305ffd83dbSDimitry Andric default: 315ffd83dbSDimitry Andric llvm_unreachable("Unknown integer condition code!"); 325ffd83dbSDimitry Andric case ISD::SETEQ: 335ffd83dbSDimitry Andric return VECC::CC_IEQ; 345ffd83dbSDimitry Andric case ISD::SETNE: 355ffd83dbSDimitry Andric return VECC::CC_INE; 365ffd83dbSDimitry Andric case ISD::SETLT: 375ffd83dbSDimitry Andric return VECC::CC_IL; 385ffd83dbSDimitry Andric case ISD::SETGT: 395ffd83dbSDimitry Andric return VECC::CC_IG; 405ffd83dbSDimitry Andric case ISD::SETLE: 415ffd83dbSDimitry Andric return VECC::CC_ILE; 425ffd83dbSDimitry Andric case ISD::SETGE: 435ffd83dbSDimitry Andric return VECC::CC_IGE; 445ffd83dbSDimitry Andric case ISD::SETULT: 455ffd83dbSDimitry Andric return VECC::CC_IL; 465ffd83dbSDimitry Andric case ISD::SETULE: 475ffd83dbSDimitry Andric return VECC::CC_ILE; 485ffd83dbSDimitry Andric case ISD::SETUGT: 495ffd83dbSDimitry Andric return VECC::CC_IG; 505ffd83dbSDimitry Andric case ISD::SETUGE: 515ffd83dbSDimitry Andric return VECC::CC_IGE; 525ffd83dbSDimitry Andric } 535ffd83dbSDimitry Andric } 545ffd83dbSDimitry Andric 555ffd83dbSDimitry Andric /// Convert a DAG floating point condition code to a VE FCC condition. 565ffd83dbSDimitry Andric inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) { 575ffd83dbSDimitry Andric switch (CC) { 585ffd83dbSDimitry Andric default: 595ffd83dbSDimitry Andric llvm_unreachable("Unknown fp condition code!"); 605ffd83dbSDimitry Andric case ISD::SETFALSE: 615ffd83dbSDimitry Andric return VECC::CC_AF; 625ffd83dbSDimitry Andric case ISD::SETEQ: 635ffd83dbSDimitry Andric case ISD::SETOEQ: 645ffd83dbSDimitry Andric return VECC::CC_EQ; 655ffd83dbSDimitry Andric case ISD::SETNE: 665ffd83dbSDimitry Andric case ISD::SETONE: 675ffd83dbSDimitry Andric return VECC::CC_NE; 685ffd83dbSDimitry Andric case ISD::SETLT: 695ffd83dbSDimitry Andric case ISD::SETOLT: 705ffd83dbSDimitry Andric return VECC::CC_L; 715ffd83dbSDimitry Andric case ISD::SETGT: 725ffd83dbSDimitry Andric case ISD::SETOGT: 735ffd83dbSDimitry Andric return VECC::CC_G; 745ffd83dbSDimitry Andric case ISD::SETLE: 755ffd83dbSDimitry Andric case ISD::SETOLE: 765ffd83dbSDimitry Andric return VECC::CC_LE; 775ffd83dbSDimitry Andric case ISD::SETGE: 785ffd83dbSDimitry Andric case ISD::SETOGE: 795ffd83dbSDimitry Andric return VECC::CC_GE; 805ffd83dbSDimitry Andric case ISD::SETO: 815ffd83dbSDimitry Andric return VECC::CC_NUM; 825ffd83dbSDimitry Andric case ISD::SETUO: 835ffd83dbSDimitry Andric return VECC::CC_NAN; 845ffd83dbSDimitry Andric case ISD::SETUEQ: 855ffd83dbSDimitry Andric return VECC::CC_EQNAN; 865ffd83dbSDimitry Andric case ISD::SETUNE: 875ffd83dbSDimitry Andric return VECC::CC_NENAN; 885ffd83dbSDimitry Andric case ISD::SETULT: 895ffd83dbSDimitry Andric return VECC::CC_LNAN; 905ffd83dbSDimitry Andric case ISD::SETUGT: 915ffd83dbSDimitry Andric return VECC::CC_GNAN; 925ffd83dbSDimitry Andric case ISD::SETULE: 935ffd83dbSDimitry Andric return VECC::CC_LENAN; 945ffd83dbSDimitry Andric case ISD::SETUGE: 955ffd83dbSDimitry Andric return VECC::CC_GENAN; 965ffd83dbSDimitry Andric case ISD::SETTRUE: 975ffd83dbSDimitry Andric return VECC::CC_AT; 985ffd83dbSDimitry Andric } 995ffd83dbSDimitry Andric } 1005ffd83dbSDimitry Andric 1015ffd83dbSDimitry Andric /// getImmVal - get immediate representation of integer value 1025ffd83dbSDimitry Andric inline static uint64_t getImmVal(const ConstantSDNode *N) { 1035ffd83dbSDimitry Andric return N->getSExtValue(); 1045ffd83dbSDimitry Andric } 1055ffd83dbSDimitry Andric 1065ffd83dbSDimitry Andric /// getFpImmVal - get immediate representation of floating point value 1075ffd83dbSDimitry Andric inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) { 1085ffd83dbSDimitry Andric const APInt &Imm = N->getValueAPF().bitcastToAPInt(); 1095ffd83dbSDimitry Andric uint64_t Val = Imm.getZExtValue(); 1105ffd83dbSDimitry Andric if (Imm.getBitWidth() == 32) { 1115ffd83dbSDimitry Andric // Immediate value of float place places at higher bits on VE. 1125ffd83dbSDimitry Andric Val <<= 32; 1135ffd83dbSDimitry Andric } 1145ffd83dbSDimitry Andric return Val; 1155ffd83dbSDimitry Andric } 1165ffd83dbSDimitry Andric 117480093f4SDimitry Andric //===--------------------------------------------------------------------===// 118480093f4SDimitry Andric /// VEDAGToDAGISel - VE specific code to select VE machine 119480093f4SDimitry Andric /// instructions for SelectionDAG operations. 120480093f4SDimitry Andric /// 121480093f4SDimitry Andric namespace { 122480093f4SDimitry Andric class VEDAGToDAGISel : public SelectionDAGISel { 123480093f4SDimitry Andric /// Subtarget - Keep a pointer to the VE Subtarget around so that we can 124480093f4SDimitry Andric /// make the right decision when generating code for different targets. 125480093f4SDimitry Andric const VESubtarget *Subtarget; 126480093f4SDimitry Andric 127480093f4SDimitry Andric public: 128480093f4SDimitry Andric explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {} 129480093f4SDimitry Andric 130480093f4SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 131480093f4SDimitry Andric Subtarget = &MF.getSubtarget<VESubtarget>(); 132480093f4SDimitry Andric return SelectionDAGISel::runOnMachineFunction(MF); 133480093f4SDimitry Andric } 134480093f4SDimitry Andric 135480093f4SDimitry Andric void Select(SDNode *N) override; 136480093f4SDimitry Andric 1375ffd83dbSDimitry Andric // Complex Pattern Selectors. 1385ffd83dbSDimitry Andric bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset); 1395ffd83dbSDimitry Andric bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset); 1405ffd83dbSDimitry Andric bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset); 1415ffd83dbSDimitry Andric bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset); 1425ffd83dbSDimitry Andric bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset); 143e8d8bef9SDimitry Andric bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset); 1445ffd83dbSDimitry Andric 145480093f4SDimitry Andric StringRef getPassName() const override { 146480093f4SDimitry Andric return "VE DAG->DAG Pattern Instruction Selection"; 147480093f4SDimitry Andric } 148480093f4SDimitry Andric 149480093f4SDimitry Andric // Include the pieces autogenerated from the target description. 150480093f4SDimitry Andric #include "VEGenDAGISel.inc" 1515ffd83dbSDimitry Andric 1525ffd83dbSDimitry Andric private: 1535ffd83dbSDimitry Andric SDNode *getGlobalBaseReg(); 1545ffd83dbSDimitry Andric 1555ffd83dbSDimitry Andric bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index); 1565ffd83dbSDimitry Andric bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset); 157480093f4SDimitry Andric }; 158480093f4SDimitry Andric } // end anonymous namespace 159480093f4SDimitry Andric 1605ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index, 1615ffd83dbSDimitry Andric SDValue &Offset) { 1625ffd83dbSDimitry Andric if (Addr.getOpcode() == ISD::FrameIndex) 1635ffd83dbSDimitry Andric return false; 1645ffd83dbSDimitry Andric if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1655ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalAddress || 1665ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 1675ffd83dbSDimitry Andric return false; // direct calls. 1685ffd83dbSDimitry Andric 1695ffd83dbSDimitry Andric SDValue LHS, RHS; 1705ffd83dbSDimitry Andric if (matchADDRri(Addr, LHS, RHS)) { 1715ffd83dbSDimitry Andric if (matchADDRrr(LHS, Base, Index)) { 1725ffd83dbSDimitry Andric Offset = RHS; 1735ffd83dbSDimitry Andric return true; 1745ffd83dbSDimitry Andric } 1755ffd83dbSDimitry Andric // Return false to try selectADDRrii. 1765ffd83dbSDimitry Andric return false; 1775ffd83dbSDimitry Andric } 1785ffd83dbSDimitry Andric if (matchADDRrr(Addr, LHS, RHS)) { 179e8d8bef9SDimitry Andric // If the input is a pair of a frame-index and a register, move a 180e8d8bef9SDimitry Andric // frame-index to LHS. This generates MI with following operands. 181e8d8bef9SDimitry Andric // %dest, #FI, %reg, offset 182e8d8bef9SDimitry Andric // In the eliminateFrameIndex, above MI is converted to the following. 183e8d8bef9SDimitry Andric // %dest, %fp, %reg, fi_offset + offset 184fe6060f1SDimitry Andric if (isa<FrameIndexSDNode>(RHS)) 185e8d8bef9SDimitry Andric std::swap(LHS, RHS); 186e8d8bef9SDimitry Andric 1875ffd83dbSDimitry Andric if (matchADDRri(RHS, Index, Offset)) { 1885ffd83dbSDimitry Andric Base = LHS; 1895ffd83dbSDimitry Andric return true; 1905ffd83dbSDimitry Andric } 1915ffd83dbSDimitry Andric if (matchADDRri(LHS, Base, Offset)) { 1925ffd83dbSDimitry Andric Index = RHS; 1935ffd83dbSDimitry Andric return true; 1945ffd83dbSDimitry Andric } 1955ffd83dbSDimitry Andric Base = LHS; 1965ffd83dbSDimitry Andric Index = RHS; 1975ffd83dbSDimitry Andric Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 1985ffd83dbSDimitry Andric return true; 1995ffd83dbSDimitry Andric } 2005ffd83dbSDimitry Andric return false; // Let the reg+imm(=0) pattern catch this! 2015ffd83dbSDimitry Andric } 2025ffd83dbSDimitry Andric 2035ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index, 2045ffd83dbSDimitry Andric SDValue &Offset) { 2055ffd83dbSDimitry Andric if (matchADDRri(Addr, Base, Offset)) { 2065ffd83dbSDimitry Andric Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2075ffd83dbSDimitry Andric return true; 2085ffd83dbSDimitry Andric } 2095ffd83dbSDimitry Andric 2105ffd83dbSDimitry Andric Base = Addr; 2115ffd83dbSDimitry Andric Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2125ffd83dbSDimitry Andric Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2135ffd83dbSDimitry Andric return true; 2145ffd83dbSDimitry Andric } 2155ffd83dbSDimitry Andric 2165ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index, 2175ffd83dbSDimitry Andric SDValue &Offset) { 2185ffd83dbSDimitry Andric // Prefer ADDRrii. 2195ffd83dbSDimitry Andric return false; 2205ffd83dbSDimitry Andric } 2215ffd83dbSDimitry Andric 2225ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index, 2235ffd83dbSDimitry Andric SDValue &Offset) { 224fe6060f1SDimitry Andric if (isa<FrameIndexSDNode>(Addr)) 2255ffd83dbSDimitry Andric return false; 2265ffd83dbSDimitry Andric if (Addr.getOpcode() == ISD::TargetExternalSymbol || 2275ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalAddress || 2285ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 2295ffd83dbSDimitry Andric return false; // direct calls. 2305ffd83dbSDimitry Andric 231e8d8bef9SDimitry Andric if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) { 2325ffd83dbSDimitry Andric if (isInt<32>(CN->getSExtValue())) { 2335ffd83dbSDimitry Andric Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2345ffd83dbSDimitry Andric Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2355ffd83dbSDimitry Andric Offset = 2365ffd83dbSDimitry Andric CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32); 2375ffd83dbSDimitry Andric return true; 2385ffd83dbSDimitry Andric } 2395ffd83dbSDimitry Andric } 2405ffd83dbSDimitry Andric return false; 2415ffd83dbSDimitry Andric } 2425ffd83dbSDimitry Andric 2435ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base, 2445ffd83dbSDimitry Andric SDValue &Offset) { 2455ffd83dbSDimitry Andric if (matchADDRri(Addr, Base, Offset)) 2465ffd83dbSDimitry Andric return true; 2475ffd83dbSDimitry Andric 2485ffd83dbSDimitry Andric Base = Addr; 2495ffd83dbSDimitry Andric Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2505ffd83dbSDimitry Andric return true; 2515ffd83dbSDimitry Andric } 2525ffd83dbSDimitry Andric 253e8d8bef9SDimitry Andric bool VEDAGToDAGISel::selectADDRzi(SDValue Addr, SDValue &Base, 254e8d8bef9SDimitry Andric SDValue &Offset) { 255fe6060f1SDimitry Andric if (isa<FrameIndexSDNode>(Addr)) 256e8d8bef9SDimitry Andric return false; 257e8d8bef9SDimitry Andric if (Addr.getOpcode() == ISD::TargetExternalSymbol || 258e8d8bef9SDimitry Andric Addr.getOpcode() == ISD::TargetGlobalAddress || 259e8d8bef9SDimitry Andric Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 260e8d8bef9SDimitry Andric return false; // direct calls. 261e8d8bef9SDimitry Andric 262e8d8bef9SDimitry Andric if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) { 263e8d8bef9SDimitry Andric if (isInt<32>(CN->getSExtValue())) { 264e8d8bef9SDimitry Andric Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 265e8d8bef9SDimitry Andric Offset = 266e8d8bef9SDimitry Andric CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32); 267e8d8bef9SDimitry Andric return true; 268e8d8bef9SDimitry Andric } 269e8d8bef9SDimitry Andric } 270e8d8bef9SDimitry Andric return false; 271e8d8bef9SDimitry Andric } 272e8d8bef9SDimitry Andric 2735ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) { 274fe6060f1SDimitry Andric if (isa<FrameIndexSDNode>(Addr)) 2755ffd83dbSDimitry Andric return false; 2765ffd83dbSDimitry Andric if (Addr.getOpcode() == ISD::TargetExternalSymbol || 2775ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalAddress || 2785ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 2795ffd83dbSDimitry Andric return false; // direct calls. 2805ffd83dbSDimitry Andric 2815ffd83dbSDimitry Andric if (Addr.getOpcode() == ISD::ADD) { 2825ffd83dbSDimitry Andric ; // Nothing to do here. 2835ffd83dbSDimitry Andric } else if (Addr.getOpcode() == ISD::OR) { 2845ffd83dbSDimitry Andric // We want to look through a transform in InstCombine and DAGCombiner that 2855ffd83dbSDimitry Andric // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'. 2865ffd83dbSDimitry Andric if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1))) 2875ffd83dbSDimitry Andric return false; 2885ffd83dbSDimitry Andric } else { 2895ffd83dbSDimitry Andric return false; 2905ffd83dbSDimitry Andric } 2915ffd83dbSDimitry Andric 2925ffd83dbSDimitry Andric if (Addr.getOperand(0).getOpcode() == VEISD::Lo || 2935ffd83dbSDimitry Andric Addr.getOperand(1).getOpcode() == VEISD::Lo) 2945ffd83dbSDimitry Andric return false; // Let the LEASL patterns catch this! 2955ffd83dbSDimitry Andric 2965ffd83dbSDimitry Andric Base = Addr.getOperand(0); 2975ffd83dbSDimitry Andric Index = Addr.getOperand(1); 2985ffd83dbSDimitry Andric return true; 2995ffd83dbSDimitry Andric } 3005ffd83dbSDimitry Andric 3015ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) { 3025ffd83dbSDimitry Andric auto AddrTy = Addr->getValueType(0); 3035ffd83dbSDimitry Andric if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 3045ffd83dbSDimitry Andric Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy); 3055ffd83dbSDimitry Andric Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 3065ffd83dbSDimitry Andric return true; 3075ffd83dbSDimitry Andric } 3085ffd83dbSDimitry Andric if (Addr.getOpcode() == ISD::TargetExternalSymbol || 3095ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalAddress || 3105ffd83dbSDimitry Andric Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 3115ffd83dbSDimitry Andric return false; // direct calls. 3125ffd83dbSDimitry Andric 3135ffd83dbSDimitry Andric if (CurDAG->isBaseWithConstantOffset(Addr)) { 3145ffd83dbSDimitry Andric ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1)); 3155ffd83dbSDimitry Andric if (isInt<32>(CN->getSExtValue())) { 3165ffd83dbSDimitry Andric if (FrameIndexSDNode *FIN = 3175ffd83dbSDimitry Andric dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { 3185ffd83dbSDimitry Andric // Constant offset from frame ref. 3195ffd83dbSDimitry Andric Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy); 3205ffd83dbSDimitry Andric } else { 3215ffd83dbSDimitry Andric Base = Addr.getOperand(0); 3225ffd83dbSDimitry Andric } 3235ffd83dbSDimitry Andric Offset = 3245ffd83dbSDimitry Andric CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32); 3255ffd83dbSDimitry Andric return true; 3265ffd83dbSDimitry Andric } 3275ffd83dbSDimitry Andric } 3285ffd83dbSDimitry Andric return false; 3295ffd83dbSDimitry Andric } 3305ffd83dbSDimitry Andric 331480093f4SDimitry Andric void VEDAGToDAGISel::Select(SDNode *N) { 332480093f4SDimitry Andric SDLoc dl(N); 333480093f4SDimitry Andric if (N->isMachineOpcode()) { 334480093f4SDimitry Andric N->setNodeId(-1); 335480093f4SDimitry Andric return; // Already selected. 336480093f4SDimitry Andric } 337480093f4SDimitry Andric 3385ffd83dbSDimitry Andric switch (N->getOpcode()) { 339*81ad6265SDimitry Andric 340*81ad6265SDimitry Andric // Late eliminate the LEGALAVL wrapper 341*81ad6265SDimitry Andric case VEISD::LEGALAVL: 342*81ad6265SDimitry Andric ReplaceNode(N, N->getOperand(0).getNode()); 343*81ad6265SDimitry Andric return; 344*81ad6265SDimitry Andric 345*81ad6265SDimitry Andric // Lower (broadcast 1) and (broadcast 0) to VM[P]0 346*81ad6265SDimitry Andric case VEISD::VEC_BROADCAST: { 347*81ad6265SDimitry Andric MVT SplatResTy = N->getSimpleValueType(0); 348*81ad6265SDimitry Andric if (SplatResTy.getVectorElementType() != MVT::i1) 349*81ad6265SDimitry Andric break; 350*81ad6265SDimitry Andric 351*81ad6265SDimitry Andric // Constant non-zero broadcast. 352*81ad6265SDimitry Andric auto BConst = dyn_cast<ConstantSDNode>(N->getOperand(0)); 353*81ad6265SDimitry Andric if (!BConst) 354*81ad6265SDimitry Andric break; 355*81ad6265SDimitry Andric bool BCTrueMask = (BConst->getSExtValue() != 0); 356*81ad6265SDimitry Andric if (!BCTrueMask) 357*81ad6265SDimitry Andric break; 358*81ad6265SDimitry Andric 359*81ad6265SDimitry Andric // Packed or non-packed. 360*81ad6265SDimitry Andric SDValue New; 361*81ad6265SDimitry Andric if (SplatResTy.getVectorNumElements() == StandardVectorWidth) { 362*81ad6265SDimitry Andric New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VM0, 363*81ad6265SDimitry Andric MVT::v256i1); 364*81ad6265SDimitry Andric } else if (SplatResTy.getVectorNumElements() == PackedVectorWidth) { 365*81ad6265SDimitry Andric New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VMP0, 366*81ad6265SDimitry Andric MVT::v512i1); 367*81ad6265SDimitry Andric } else 368*81ad6265SDimitry Andric break; 369*81ad6265SDimitry Andric 370*81ad6265SDimitry Andric // Replace. 371*81ad6265SDimitry Andric ReplaceNode(N, New.getNode()); 372*81ad6265SDimitry Andric return; 373*81ad6265SDimitry Andric } 374*81ad6265SDimitry Andric 3755ffd83dbSDimitry Andric case VEISD::GLOBAL_BASE_REG: 3765ffd83dbSDimitry Andric ReplaceNode(N, getGlobalBaseReg()); 3775ffd83dbSDimitry Andric return; 3785ffd83dbSDimitry Andric } 3795ffd83dbSDimitry Andric 380480093f4SDimitry Andric SelectCode(N); 381480093f4SDimitry Andric } 382480093f4SDimitry Andric 3835ffd83dbSDimitry Andric SDNode *VEDAGToDAGISel::getGlobalBaseReg() { 3845ffd83dbSDimitry Andric Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF); 3855ffd83dbSDimitry Andric return CurDAG 3865ffd83dbSDimitry Andric ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout())) 3875ffd83dbSDimitry Andric .getNode(); 3885ffd83dbSDimitry Andric } 3895ffd83dbSDimitry Andric 390480093f4SDimitry Andric /// createVEISelDag - This pass converts a legalized DAG into a 391480093f4SDimitry Andric /// VE-specific DAG, ready for instruction scheduling. 392480093f4SDimitry Andric /// 393480093f4SDimitry Andric FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) { 394480093f4SDimitry Andric return new VEDAGToDAGISel(TM); 395480093f4SDimitry Andric } 396