10b57cec5SDimitry Andric //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines an instruction selector for the MIPS target. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MipsISelDAGToDAG.h" 140b57cec5SDimitry Andric #include "MCTargetDesc/MipsBaseInfo.h" 150b57cec5SDimitry Andric #include "Mips.h" 160b57cec5SDimitry Andric #include "Mips16ISelDAGToDAG.h" 170b57cec5SDimitry Andric #include "MipsMachineFunction.h" 180b57cec5SDimitry Andric #include "MipsRegisterInfo.h" 190b57cec5SDimitry Andric #include "MipsSEISelDAGToDAG.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 25647cbc5dSDimitry Andric #include "llvm/CodeGen/SelectionDAG.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/StackProtector.h" 280b57cec5SDimitry Andric #include "llvm/IR/CFG.h" 290b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 300b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 310b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 320b57cec5SDimitry Andric #include "llvm/IR/Type.h" 330b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 340b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 35647cbc5dSDimitry Andric #include "llvm/Support/KnownBits.h" 360b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 370b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 380b57cec5SDimitry Andric using namespace llvm; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric #define DEBUG_TYPE "mips-isel" 41bdd1243dSDimitry Andric #define PASS_NAME "MIPS DAG->DAG Pattern Instruction Selection" 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 440b57cec5SDimitry Andric // Instruction Selector Implementation 450b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 480b57cec5SDimitry Andric // MipsDAGToDAGISel - MIPS specific code to select MIPS machine 490b57cec5SDimitry Andric // instructions for SelectionDAG operations. 500b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 510b57cec5SDimitry Andric 520fca6ea1SDimitry Andric void MipsDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { 530b57cec5SDimitry Andric // There are multiple MipsDAGToDAGISel instances added to the pass pipeline. 540b57cec5SDimitry Andric // We need to preserve StackProtector for the next one. 550b57cec5SDimitry Andric AU.addPreserved<StackProtector>(); 560fca6ea1SDimitry Andric SelectionDAGISelLegacy::getAnalysisUsage(AU); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 6081ad6265SDimitry Andric Subtarget = &MF.getSubtarget<MipsSubtarget>(); 610b57cec5SDimitry Andric bool Ret = SelectionDAGISel::runOnMachineFunction(MF); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric processFunctionAfterISel(MF); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric return Ret; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// getGlobalBaseReg - Output the instructions required to put the 690b57cec5SDimitry Andric /// GOT address into a register. 700b57cec5SDimitry Andric SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { 715ffd83dbSDimitry Andric Register GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg(*MF); 720b57cec5SDimitry Andric return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy( 730b57cec5SDimitry Andric CurDAG->getDataLayout())) 740b57cec5SDimitry Andric .getNode(); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric /// ComplexPattern used on MipsInstrInfo 780b57cec5SDimitry Andric /// Used on Mips Load/Store instructions 790b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, 800b57cec5SDimitry Andric SDValue &Offset) const { 810b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 820b57cec5SDimitry Andric return false; 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, 860b57cec5SDimitry Andric SDValue &Offset) const { 870b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 880b57cec5SDimitry Andric return false; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, 920b57cec5SDimitry Andric SDValue &Offset) const { 930b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 940b57cec5SDimitry Andric return false; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base, 980b57cec5SDimitry Andric SDValue &Offset) const { 990b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1000b57cec5SDimitry Andric return false; 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base, 1040b57cec5SDimitry Andric SDValue &Offset) const { 1050b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1060b57cec5SDimitry Andric return false; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base, 1100b57cec5SDimitry Andric SDValue &Offset) const { 1110b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1120b57cec5SDimitry Andric return false; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, 1160b57cec5SDimitry Andric SDValue &Offset) const { 1170b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1180b57cec5SDimitry Andric return false; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, 1220b57cec5SDimitry Andric SDValue &Offset) const { 1230b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1240b57cec5SDimitry Andric return false; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, 1280b57cec5SDimitry Andric SDValue &Offset) const { 1290b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1300b57cec5SDimitry Andric return false; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, 1340b57cec5SDimitry Andric SDValue &Offset) const { 1350b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1360b57cec5SDimitry Andric return false; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, 1400b57cec5SDimitry Andric SDValue &Offset) const { 1410b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1420b57cec5SDimitry Andric return false; 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base, 1460b57cec5SDimitry Andric SDValue &Offset) { 1470b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1480b57cec5SDimitry Andric return false; 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base, 1520b57cec5SDimitry Andric SDValue &Offset) { 1530b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1540b57cec5SDimitry Andric return false; 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, 1580b57cec5SDimitry Andric unsigned MinSizeInBits) const { 1590b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1600b57cec5SDimitry Andric return false; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const { 1640b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1650b57cec5SDimitry Andric return false; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const { 1690b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1700b57cec5SDimitry Andric return false; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const { 1740b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1750b57cec5SDimitry Andric return false; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const { 1790b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1800b57cec5SDimitry Andric return false; 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const { 1840b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1850b57cec5SDimitry Andric return false; 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const { 1890b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1900b57cec5SDimitry Andric return false; 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const { 1940b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 1950b57cec5SDimitry Andric return false; 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const { 1990b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 2000b57cec5SDimitry Andric return false; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const { 2040b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 2050b57cec5SDimitry Andric return false; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const { 2090b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 2100b57cec5SDimitry Andric return false; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const { 2140b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 2150b57cec5SDimitry Andric return false; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const { 2190b57cec5SDimitry Andric llvm_unreachable("Unimplemented function."); 2200b57cec5SDimitry Andric return false; 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 223*71ac745dSDimitry Andric bool MipsDAGToDAGISel::selectVSplatImmEq1(SDValue N) const { 224*71ac745dSDimitry Andric llvm_unreachable("Unimplemented function."); 225*71ac745dSDimitry Andric } 226*71ac745dSDimitry Andric 2278bcb0991SDimitry Andric /// Convert vector addition with vector subtraction if that allows to encode 2288bcb0991SDimitry Andric /// constant as an immediate and thus avoid extra 'ldi' instruction. 2298bcb0991SDimitry Andric /// add X, <-1, -1...> --> sub X, <1, 1...> 2308bcb0991SDimitry Andric bool MipsDAGToDAGISel::selectVecAddAsVecSubIfProfitable(SDNode *Node) { 2318bcb0991SDimitry Andric assert(Node->getOpcode() == ISD::ADD && "Should only get 'add' here."); 2328bcb0991SDimitry Andric 2338bcb0991SDimitry Andric EVT VT = Node->getValueType(0); 2348bcb0991SDimitry Andric assert(VT.isVector() && "Should only be called for vectors."); 2358bcb0991SDimitry Andric 2368bcb0991SDimitry Andric SDValue X = Node->getOperand(0); 2378bcb0991SDimitry Andric SDValue C = Node->getOperand(1); 2388bcb0991SDimitry Andric 2398bcb0991SDimitry Andric auto *BVN = dyn_cast<BuildVectorSDNode>(C); 2408bcb0991SDimitry Andric if (!BVN) 2418bcb0991SDimitry Andric return false; 2428bcb0991SDimitry Andric 2438bcb0991SDimitry Andric APInt SplatValue, SplatUndef; 2448bcb0991SDimitry Andric unsigned SplatBitSize; 2458bcb0991SDimitry Andric bool HasAnyUndefs; 2468bcb0991SDimitry Andric 2478bcb0991SDimitry Andric if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, 2488bcb0991SDimitry Andric 8, !Subtarget->isLittle())) 2498bcb0991SDimitry Andric return false; 2508bcb0991SDimitry Andric 2518bcb0991SDimitry Andric auto IsInlineConstant = [](const APInt &Imm) { return Imm.isIntN(5); }; 2528bcb0991SDimitry Andric 2538bcb0991SDimitry Andric if (IsInlineConstant(SplatValue)) 2548bcb0991SDimitry Andric return false; // Can already be encoded as an immediate. 2558bcb0991SDimitry Andric 2568bcb0991SDimitry Andric APInt NegSplatValue = 0 - SplatValue; 2578bcb0991SDimitry Andric if (!IsInlineConstant(NegSplatValue)) 2588bcb0991SDimitry Andric return false; // Even if we negate it it won't help. 2598bcb0991SDimitry Andric 2608bcb0991SDimitry Andric SDLoc DL(Node); 2618bcb0991SDimitry Andric 2628bcb0991SDimitry Andric SDValue NegC = CurDAG->FoldConstantArithmetic( 2635ffd83dbSDimitry Andric ISD::SUB, DL, VT, {CurDAG->getConstant(0, DL, VT), C}); 2648bcb0991SDimitry Andric assert(NegC && "Constant-folding failed!"); 2658bcb0991SDimitry Andric SDValue NewNode = CurDAG->getNode(ISD::SUB, DL, VT, X, NegC); 2668bcb0991SDimitry Andric 2678bcb0991SDimitry Andric ReplaceNode(Node, NewNode.getNode()); 2688bcb0991SDimitry Andric SelectCode(NewNode.getNode()); 2698bcb0991SDimitry Andric return true; 2708bcb0991SDimitry Andric } 2718bcb0991SDimitry Andric 2720b57cec5SDimitry Andric /// Select instructions not customized! Used for 2730b57cec5SDimitry Andric /// expanded, promoted and normal instructions 2740b57cec5SDimitry Andric void MipsDAGToDAGISel::Select(SDNode *Node) { 2750b57cec5SDimitry Andric unsigned Opcode = Node->getOpcode(); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // If we have a custom node, we already have selected! 2780b57cec5SDimitry Andric if (Node->isMachineOpcode()) { 2790b57cec5SDimitry Andric LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 2800b57cec5SDimitry Andric Node->setNodeId(-1); 2810b57cec5SDimitry Andric return; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric // See if subclasses can handle this node. 2850b57cec5SDimitry Andric if (trySelect(Node)) 2860b57cec5SDimitry Andric return; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric switch(Opcode) { 2890b57cec5SDimitry Andric default: break; 2900b57cec5SDimitry Andric 2918bcb0991SDimitry Andric case ISD::ADD: 2928bcb0991SDimitry Andric if (Node->getSimpleValueType(0).isVector() && 2938bcb0991SDimitry Andric selectVecAddAsVecSubIfProfitable(Node)) 2948bcb0991SDimitry Andric return; 2958bcb0991SDimitry Andric break; 2968bcb0991SDimitry Andric 2970b57cec5SDimitry Andric // Get target GOT address. 2980b57cec5SDimitry Andric case ISD::GLOBAL_OFFSET_TABLE: 2990b57cec5SDimitry Andric ReplaceNode(Node, getGlobalBaseReg()); 3000b57cec5SDimitry Andric return; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric #ifndef NDEBUG 3030b57cec5SDimitry Andric case ISD::LOAD: 3040b57cec5SDimitry Andric case ISD::STORE: 3050b57cec5SDimitry Andric assert((Subtarget->systemSupportsUnalignedAccess() || 306bdd1243dSDimitry Andric cast<MemSDNode>(Node)->getAlign() >= 307bdd1243dSDimitry Andric cast<MemSDNode>(Node)->getMemoryVT().getStoreSize()) && 3080b57cec5SDimitry Andric "Unexpected unaligned loads/stores."); 3090b57cec5SDimitry Andric break; 3100b57cec5SDimitry Andric #endif 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric // Select the default instruction 3140b57cec5SDimitry Andric SelectCode(Node); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3175f757f3fSDimitry Andric bool MipsDAGToDAGISel::SelectInlineAsmMemoryOperand( 3185f757f3fSDimitry Andric const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, 3190b57cec5SDimitry Andric std::vector<SDValue> &OutOps) { 3200b57cec5SDimitry Andric // All memory constraints can at least accept raw pointers. 3210b57cec5SDimitry Andric switch(ConstraintID) { 3220b57cec5SDimitry Andric default: 3230b57cec5SDimitry Andric llvm_unreachable("Unexpected asm memory constraint"); 3245f757f3fSDimitry Andric case InlineAsm::ConstraintCode::m: 3255f757f3fSDimitry Andric case InlineAsm::ConstraintCode::R: 3265f757f3fSDimitry Andric case InlineAsm::ConstraintCode::ZC: 3270b57cec5SDimitry Andric OutOps.push_back(Op); 3280b57cec5SDimitry Andric return false; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric return true; 3310b57cec5SDimitry Andric } 332bdd1243dSDimitry Andric 333647cbc5dSDimitry Andric bool MipsDAGToDAGISel::isUnneededShiftMask(SDNode *N, 334647cbc5dSDimitry Andric unsigned ShAmtBits) const { 335647cbc5dSDimitry Andric assert(N->getOpcode() == ISD::AND && "Unexpected opcode"); 336647cbc5dSDimitry Andric 337647cbc5dSDimitry Andric const APInt &RHS = N->getConstantOperandAPInt(1); 338647cbc5dSDimitry Andric if (RHS.countr_one() >= ShAmtBits) { 339647cbc5dSDimitry Andric LLVM_DEBUG( 340647cbc5dSDimitry Andric dbgs() 341647cbc5dSDimitry Andric << DEBUG_TYPE 342647cbc5dSDimitry Andric << " Need optimize 'and & shl/srl/sra' and operand value bits is " 343647cbc5dSDimitry Andric << RHS.countr_one() << "\n"); 344647cbc5dSDimitry Andric return true; 345647cbc5dSDimitry Andric } 346647cbc5dSDimitry Andric 347647cbc5dSDimitry Andric KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0)); 348647cbc5dSDimitry Andric return (Known.Zero | RHS).countr_one() >= ShAmtBits; 349647cbc5dSDimitry Andric } 350647cbc5dSDimitry Andric 3510fca6ea1SDimitry Andric char MipsDAGToDAGISelLegacy::ID = 0; 352bdd1243dSDimitry Andric 3530fca6ea1SDimitry Andric MipsDAGToDAGISelLegacy::MipsDAGToDAGISelLegacy( 3540fca6ea1SDimitry Andric std::unique_ptr<SelectionDAGISel> S) 3550fca6ea1SDimitry Andric : SelectionDAGISelLegacy(ID, std::move(S)) {} 3560fca6ea1SDimitry Andric 3570fca6ea1SDimitry Andric INITIALIZE_PASS(MipsDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) 358