1*04eeddc0SDimitry Andric //===-- VECustomDAG.h - VE Custom DAG Nodes ------------*- C++ -*-===// 2*04eeddc0SDimitry Andric // 3*04eeddc0SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*04eeddc0SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*04eeddc0SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*04eeddc0SDimitry Andric // 7*04eeddc0SDimitry Andric //===----------------------------------------------------------------------===// 8*04eeddc0SDimitry Andric // 9*04eeddc0SDimitry Andric // This file defines the interfaces that VE uses to lower LLVM code into a 10*04eeddc0SDimitry Andric // selection DAG. 11*04eeddc0SDimitry Andric // 12*04eeddc0SDimitry Andric //===----------------------------------------------------------------------===// 13*04eeddc0SDimitry Andric 14*04eeddc0SDimitry Andric #include "VECustomDAG.h" 15*04eeddc0SDimitry Andric 16*04eeddc0SDimitry Andric #ifndef DEBUG_TYPE 17*04eeddc0SDimitry Andric #define DEBUG_TYPE "vecustomdag" 18*04eeddc0SDimitry Andric #endif 19*04eeddc0SDimitry Andric 20*04eeddc0SDimitry Andric namespace llvm { 21*04eeddc0SDimitry Andric 22*04eeddc0SDimitry Andric static const int StandardVectorWidth = 256; 23*04eeddc0SDimitry Andric 24*04eeddc0SDimitry Andric bool isPackedVectorType(EVT SomeVT) { 25*04eeddc0SDimitry Andric if (!SomeVT.isVector()) 26*04eeddc0SDimitry Andric return false; 27*04eeddc0SDimitry Andric return SomeVT.getVectorNumElements() > StandardVectorWidth; 28*04eeddc0SDimitry Andric } 29*04eeddc0SDimitry Andric 30*04eeddc0SDimitry Andric /// \returns the VVP_* SDNode opcode corresponsing to \p OC. 31*04eeddc0SDimitry Andric Optional<unsigned> getVVPOpcode(unsigned Opcode) { 32*04eeddc0SDimitry Andric switch (Opcode) { 33*04eeddc0SDimitry Andric #define HANDLE_VP_TO_VVP(VPOPC, VVPNAME) \ 34*04eeddc0SDimitry Andric case ISD::VPOPC: \ 35*04eeddc0SDimitry Andric return VEISD::VVPNAME; 36*04eeddc0SDimitry Andric #define ADD_VVP_OP(VVPNAME, SDNAME) \ 37*04eeddc0SDimitry Andric case VEISD::VVPNAME: \ 38*04eeddc0SDimitry Andric case ISD::SDNAME: \ 39*04eeddc0SDimitry Andric return VEISD::VVPNAME; 40*04eeddc0SDimitry Andric #include "VVPNodes.def" 41*04eeddc0SDimitry Andric } 42*04eeddc0SDimitry Andric return None; 43*04eeddc0SDimitry Andric } 44*04eeddc0SDimitry Andric 45*04eeddc0SDimitry Andric bool isVVPBinaryOp(unsigned VVPOpcode) { 46*04eeddc0SDimitry Andric switch (VVPOpcode) { 47*04eeddc0SDimitry Andric #define ADD_BINARY_VVP_OP(VVPNAME, ...) \ 48*04eeddc0SDimitry Andric case VEISD::VVPNAME: \ 49*04eeddc0SDimitry Andric return true; 50*04eeddc0SDimitry Andric #include "VVPNodes.def" 51*04eeddc0SDimitry Andric } 52*04eeddc0SDimitry Andric return false; 53*04eeddc0SDimitry Andric } 54*04eeddc0SDimitry Andric 55*04eeddc0SDimitry Andric SDValue VECustomDAG::getConstant(uint64_t Val, EVT VT, bool IsTarget, 56*04eeddc0SDimitry Andric bool IsOpaque) const { 57*04eeddc0SDimitry Andric return DAG.getConstant(Val, DL, VT, IsTarget, IsOpaque); 58*04eeddc0SDimitry Andric } 59*04eeddc0SDimitry Andric 60*04eeddc0SDimitry Andric SDValue VECustomDAG::getBroadcast(EVT ResultVT, SDValue Scalar, 61*04eeddc0SDimitry Andric SDValue AVL) const { 62*04eeddc0SDimitry Andric assert(ResultVT.isVector()); 63*04eeddc0SDimitry Andric auto ScaVT = Scalar.getValueType(); 64*04eeddc0SDimitry Andric assert(ScaVT != MVT::i1 && "TODO: Mask broadcasts"); 65*04eeddc0SDimitry Andric 66*04eeddc0SDimitry Andric if (isPackedVectorType(ResultVT)) { 67*04eeddc0SDimitry Andric // v512x packed mode broadcast 68*04eeddc0SDimitry Andric // Replicate the scalar reg (f32 or i32) onto the opposing half of the full 69*04eeddc0SDimitry Andric // scalar register. If it's an I64 type, assume that this has already 70*04eeddc0SDimitry Andric // happened. 71*04eeddc0SDimitry Andric if (ScaVT == MVT::f32) { 72*04eeddc0SDimitry Andric Scalar = getNode(VEISD::REPL_F32, MVT::i64, Scalar); 73*04eeddc0SDimitry Andric } else if (ScaVT == MVT::i32) { 74*04eeddc0SDimitry Andric Scalar = getNode(VEISD::REPL_I32, MVT::i64, Scalar); 75*04eeddc0SDimitry Andric } 76*04eeddc0SDimitry Andric } 77*04eeddc0SDimitry Andric 78*04eeddc0SDimitry Andric return getNode(VEISD::VEC_BROADCAST, ResultVT, {Scalar, AVL}); 79*04eeddc0SDimitry Andric } 80*04eeddc0SDimitry Andric 81*04eeddc0SDimitry Andric } // namespace llvm 82