xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/VEISelDAGToDAG.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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