xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VECustomDAG.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
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