1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines a pattern matching instruction selector for the Cell SPU, 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// converting from a legalized dag to a SPU-target dag. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPU.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUTargetMachine.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUHazardRecognizers.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "SPUFrameLowering.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUTargetMachine.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineConstantPool.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAG.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAGISel.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/PseudoSourceValue.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetOptions.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/Statistic.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Constants.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/GlobalValue.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Intrinsics.h" 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/LLVMContext.h" 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MathExtras.h" 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Compiler.h" 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isI32IntS10Immediate(ConstantSDNode *CN) 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return isInt<10>(CN->getSExtValue()); 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isI32IntU10Immediate(ConstantSDNode *CN) 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return isUInt<10>(CN->getSExtValue()); 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isI16IntS10Immediate(ConstantSDNode *CN) 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return isInt<10>(CN->getSExtValue()); 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isI16IntU10Immediate(ConstantSDNode *CN) 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return isUInt<10>((short) CN->getZExtValue()); 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! ConstantSDNode predicate for signed 16-bit values 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*! 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg CN The constant SelectionDAG node holding the value 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Imm The returned 16-bit value, if returning true 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman This predicate tests the value in \a CN to see whether it can be 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman represented as a 16-bit, sign-extended quantity. Returns true if 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman this is the case. 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isIntS16Immediate(ConstantSDNode *CN, short &Imm) 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT vt = CN->getValueType(0); 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Imm = (short) CN->getZExtValue(); 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (vt == MVT::i32) { 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int32_t i_val = (int32_t) CN->getZExtValue(); 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman short s_val = (short) i_val; 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return i_val == s_val; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t i_val = (int64_t) CN->getZExtValue(); 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman short s_val = (short) i_val; 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return i_val == s_val; 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static bool 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT vt = FPN->getValueType(0); 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (vt == MVT::f32) { 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int sval = (int) ((val << 16) >> 16); 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Imm = (short) val; 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return val == sval; 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Generate the carry-generate shuffle mask. 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16 > ShufBytes; 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create the shuffle mask for "rotating" the borrow up one register slot 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // once the borrow is generated. 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ShufBytes[0], ShufBytes.size()); 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Generate the borrow-generate shuffle mask 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16 > ShufBytes; 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create the shuffle mask for "rotating" the borrow up one register slot 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // once the borrow is generated. 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ShufBytes[0], ShufBytes.size()); 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //===------------------------------------------------------------------===// 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// instructions for SelectionDAG operations. 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class SPUDAGToDAGISel : 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public SelectionDAGISel 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SPUTargetMachine &TM; 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SPUTargetLowering &SPUtli; 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned GlobalBaseReg; 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAGISel(tm), 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TM(tm), 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPUtli(*tm.getTargetLowering()) 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { } 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual bool runOnMachineFunction(MachineFunction &MF) { 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure we re-emit a set of the global base reg if necessary 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GlobalBaseReg = 0; 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAGISel::runOnMachineFunction(MF); 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getI32Imm - Return a target constant with the specified value, of type 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// i32. 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman inline SDValue getI32Imm(uint32_t Imm) { 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getTargetConstant(Imm, MVT::i32); 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getSmallIPtrImm - Return a target constant of pointer type. 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman inline SDValue getSmallIPtrImm(unsigned Imm) { 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *emitBuildVector(SDNode *bvNode) { 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT vecVT = bvNode->getValueType(0); 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = bvNode->getDebugLoc(); 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check to see if this vector can be represented as a CellSPU immediate 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // constant by invoking all of the instruction selection predicates: 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (((vecVT == MVT::v8i16) && 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((vecVT == MVT::v4i32) && 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((vecVT == MVT::v2i64) && 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) { 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(SDValue(bvNode, 0)); 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = Select(bvNode)) 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return N; 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Dummy.getValue().getNode(); 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // No, need to emit a constant pool spill: 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<Constant*> CV; 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (size_t i = 0; i < bvNode->getNumOperands(); ++i) { 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i)); 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Constant *CP = ConstantVector::get(CV); 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CGPoolOffset = 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::LowerConstantPool(CPIdx, *CurDAG, TM); 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl, 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getEntryNode(), CGPoolOffset, 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getConstantPool(), 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, Alignment)); 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue()); 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return N; 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Dummy.getValue().getNode(); 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Select - Convert the specified operand from a target-independent to a 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// target-specific node if it hasn't already been changed. 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Select(SDNode *N); 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Emit the instruction sequence for i64 shl 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SelectSHLi64(SDNode *N, EVT OpVT); 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Emit the instruction sequence for i64 srl 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SelectSRLi64(SDNode *N, EVT OpVT); 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Emit the instruction sequence for i64 sra 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SelectSRAi64(SDNode *N, EVT OpVT); 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Emit the necessary sequence for loading i64 constants: 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl); 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Alternate instruction emit sequence for loading i64 constants 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl); 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Returns true if the address N is an A-form (local store) address 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index); 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! D-form address predicate 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Alternate D-form address using i7 offset predicate 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Base); 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// D-form address selection workhorse 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp, 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Base, int minOffset, int maxOffset); 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Address predicate if N can be expressed as an indexed [r+r] operation. 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index); 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// inline asm expressions. 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char ConstraintCode, 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<SDValue> &OutOps) { 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0, Op1; 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (ConstraintCode) { 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: return true; 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'm': // memory 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectXFormAddr(Op.getNode(), Op, Op0, Op1); 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'o': // offsetable 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) { 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0 = Op; 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op1 = getSmallIPtrImm(0); 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'v': // not offsetable 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 1 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled."); 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#else 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectAddrIdxOnly(Op, Op, Op0, Op1); 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutOps.push_back(Op0); 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutOps.push_back(Op1); 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual const char *getPassName() const { 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "Cell SPU DAG->DAG Pattern Instruction Selection"; 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private: 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue getRC( MVT ); 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Include the pieces autogenerated from the target description. 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUGenDAGISel.inc" 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Op The ISD instruction operand 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg N The address to be tested 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Base The base address 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Index The base address index 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index) { 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // These match the addr256k operand type: 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OffsVT = MVT::i16; 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t val; 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N.getOpcode()) { 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::Constant: 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman val = dyn_cast<ConstantSDNode>(N.getNode())->getSExtValue(); 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Base = CurDAG->getTargetConstant( val , MVT::i32); 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Index = Zero; 33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; break; 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ConstantPool: 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::GlobalAddress: 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("SPU SelectAFormAddr: Pool/Global not lowered."); 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TargetConstant: 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TargetGlobalAddress: 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TargetJumpTable: 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global " 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "not wrapped as A-form address."); 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::AFormAddr: 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Just load from memory if there's only a single use of the location, 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // otherwise, this will get handled below with D-form offset addresses 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N.hasOneUse()) { 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N.getOperand(0); 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op0.getOpcode()) { 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TargetConstantPool: 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TargetJumpTable: 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = Op0; 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = Zero; 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TargetGlobalAddress: { 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const GlobalValue *GV = GSDN->getGlobal(); 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (GV->getAlignment() == 16) { 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = Op0; 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = Zero; 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Base) { 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const int minDForm2Offset = -(1 << 7); 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const int maxDForm2Offset = (1 << 7) - 1; 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maxDForm2Offset); 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Op The ISD instruction (ignored) 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg N The address to be tested 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Base Base address register/pointer 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Index Base address index 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Examine the input address by a base register plus a signed 10-bit 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman displacement, [r+I10] (D-form address). 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \return true if \a N is a D-form address with \a Base and \a Index set 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman to non-empty SDValue instances. 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman*/ 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index) { 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DFormAddressPredicate(Op, N, Base, Index, 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SPUFrameLowering::minFrameOffset(), 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SPUFrameLowering::maxFrameOffset()); 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index, int minOffset, 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int maxOffset) { 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = N.getOpcode(); 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrTy = SPUtli.getPointerTy(); 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Opc == ISD::FrameIndex) { 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Stack frame index must be less than 512 (divided by 16): 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N); 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = int(FIN->getIndex()); 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = " 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << FI << "\n"); 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) { 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(0, PtrTy); 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::ADD) { 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Generated by getelementptr 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SDValue Op0 = N.getOperand(0); 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SDValue Op1 = N.getOperand(1); 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(0, PtrTy); 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N; 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Op1.getOpcode() == ISD::Constant 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || Op1.getOpcode() == ISD::TargetConstant) { 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int32_t offset = int32_t(CN->getSExtValue()); 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getOpcode() == ISD::FrameIndex) { 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0); 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = int(FIN->getIndex()); 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " frame index = " << FI << "\n"); 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) { 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(offset, PtrTy); 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (offset > minOffset && offset < maxOffset) { 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(offset, PtrTy); 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = Op0; 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Op0.getOpcode() == ISD::Constant 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || Op0.getOpcode() == ISD::TargetConstant) { 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int32_t offset = int32_t(CN->getSExtValue()); 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op1.getOpcode() == ISD::FrameIndex) { 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1); 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = int(FIN->getIndex()); 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " frame index = " << FI << "\n"); 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) { 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(offset, PtrTy); 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (offset > minOffset && offset < maxOffset) { 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(offset, PtrTy); 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = Op1; 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == SPUISD::IndirectAddr) { 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Indirect with constant offset -> D-Form address 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SDValue Op0 = N.getOperand(0); 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SDValue Op1 = N.getOperand(1); 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getOpcode() == SPUISD::Hi 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && Op1.getOpcode() == SPUISD::Lo) { 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(0, PtrTy); 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N; 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int32_t offset = 0; 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue idxOp; 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isa<ConstantSDNode>(Op1)) { 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman offset = int32_t(CN->getSExtValue()); 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman idxOp = Op0; 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (isa<ConstantSDNode>(Op0)) { 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman offset = int32_t(CN->getSExtValue()); 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman idxOp = Op1; 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (offset >= minOffset && offset <= maxOffset) { 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(offset, PtrTy); 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = idxOp; 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == SPUISD::AFormAddr) { 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(0, N.getValueType()); 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N; 506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == SPUISD::LDRESULT) { 508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(0, N.getValueType()); 509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N; 510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (Opc == ISD::Register 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ||Opc == ISD::CopyFromReg 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ||Opc == ISD::UNDEF 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ||Opc == ISD::Constant) { 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned OpOpc = Op->getOpcode(); 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Direct load/store without getelementptr 519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Offs; 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2)); 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Offs.getOpcode() == ISD::UNDEF) 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = Offs; 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N; 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /* If otherwise unadorned, default to D-form address with 0 offset: */ 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Opc == ISD::CopyFromReg) { 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N.getOperand(1); 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N; 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetConstant(0, Index.getValueType()); 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Op The ISD instruction operand 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg N The address operand 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Base The base pointer operand 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Index The offset/index operand 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman If the address \a N can be expressed as an A-form or D-form address, returns 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false. Otherwise, creates two operands, Base and Index that will become the 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (r)(r) X-form address. 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman*/ 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Index) { 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!SelectAFormAddr(Op, N, Base, Index) 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && !SelectDFormAddr(Op, N, Base, Index)) { 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the address is neither A-form or D-form, punt and use an X-form 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // address: 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = N.getOperand(1); 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = N.getOperand(0); 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*! 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman to be used as the last parameter of a 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman \arg VT the value type for which we want a register class 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman*/ 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue SPUDAGToDAGISel::getRC( MVT VT ) { 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch( VT.SimpleTy ) { 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32); 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32); 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32); 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::f32: 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32); 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32); 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i128: 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32); 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::v16i8: 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::v8i16: 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::v4i32: 60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::v4f32: 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::v2i64: 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::v2f64: 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32); 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert( false && "add a new case here" ); 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SDValue(); 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Convert the operand from a target-independent to a target-specific node 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode * 616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::Select(SDNode *N) { 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = N->getOpcode(); 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int n_ops = -1; 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NewOpc = 0; 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = N->getValueType(0); 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[8]; 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->isMachineOpcode()) 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return NULL; // Already selected. 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Opc == ISD::FrameIndex) { 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = cast<FrameIndexSDNode>(N)->getIndex(); 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0)); 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0)); 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FI < 128) { 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOpc = SPU::AIr32; 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = TFI; 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[1] = Imm0; 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n_ops = 2; 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOpc = SPU::Ar32; 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0)); 640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl, 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getValueType(0), TFI), 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 0); 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n_ops = 2; 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Catch the i64 constants that end up here. Note: The backend doesn't 647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // attempt to legalize the constant (it's useless because DAGCombiner 648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // will insert 64-bit constants and we can't stop it). 649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectI64Constant(N, OpVT, N->getDebugLoc()); 650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && OpVT == MVT::i64) { 652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); 653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT Op0VT = Op0.getValueType(); 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(), 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0VT, (128 / Op0VT.getSizeInBits())); 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpVT, (128 / OpVT.getSizeInBits())); 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue shufMask; 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op0VT.getSimpleVT().SimpleTy) { 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT"); 663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808080, MVT::i32), 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x00010203, MVT::i32), 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808080, MVT::i32), 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x08090a0b, MVT::i32)); 670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808080, MVT::i32), 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80800203, MVT::i32), 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808080, MVT::i32), 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80800a0b, MVT::i32)); 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808080, MVT::i32), 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808003, MVT::i32), 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x80808080, MVT::i32), 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getConstant(0x8080800b, MVT::i32)); 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode()); 69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0VecVT, Op0)); 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue PromScalar; 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode())) 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PromScalar = SDValue(N, 0); 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PromScalar = PromoteScalar.getValue(); 69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue zextShuffle = 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PromScalar, PromScalar, 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(shufMaskLoad, 0)); 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy2(zextShuffle); 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = SelectCode(Dummy2.getValue().getNode())) 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman zextShuffle = SDValue(N, 0); 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman zextShuffle = Dummy2.getValue(); 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman zextShuffle)); 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectCode(Dummy.getValue().getNode()); 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Dummy.getValue().getNode(); 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *CGLoad = 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0), N->getOperand(1), 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(CGLoad, 0))); 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return N; 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Dummy.getValue().getNode(); 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *CGLoad = 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode()); 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0), N->getOperand(1), 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(CGLoad, 0))); 73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return N; 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Dummy.getValue().getNode(); 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *CGLoad = 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0), N->getOperand(1), 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(CGLoad, 0))); 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return N; 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Dummy.getValue().getNode(); 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::TRUNCATE) { 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && OpVT == MVT::i32 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && Op0.getValueType() == MVT::i64) { 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Take advantage of the fact that the upper 32 bits are in the 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // i32 preferred slot and avoid shuffle gymnastics: 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CN != 0) { 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned shift_amt = unsigned(CN->getZExtValue()); 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (shift_amt >= 32) { 765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *hi32 = 76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0.getOperand(0), getRC(MVT::i32)); 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman shift_amt -= 32; 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (shift_amt > 0) { 771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Take care of the additional shift, if present: 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = SPU::ROTMAIr32_i32; 774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getOpcode() == ISD::SRL) 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Opc = SPU::ROTMr32; 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0), 779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman shift); 780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return hi32; 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::SHL) { 787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT == MVT::i64) 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectSHLi64(N, OpVT); 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::SRL) { 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT == MVT::i64) 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectSRLi64(N, OpVT); 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::SRA) { 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT == MVT::i64) 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectSRAi64(N, OpVT); 795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::FNEG 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check if the pattern is a special form of DFNMS: 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getOpcode() == ISD::FSUB) { 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op00 = Op0.getOperand(0); 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op00.getOpcode() == ISD::FMUL) { 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = SPU::DFNMSf64; 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT == MVT::v2f64) 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Opc = SPU::DFNMSv2f64; 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getMachineNode(Opc, dl, OpVT, 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op00.getOperand(0), 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op00.getOperand(1), 811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0.getOperand(1)); 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64); 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *signMask = 0; 817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = SPU::XORfneg64; 818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT == MVT::f64) { 820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl); 821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (OpVT == MVT::v2f64) { 822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Opc = SPU::XORfnegvec; 823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::v2i64, 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman negConst, negConst).getNode()); 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getMachineNode(Opc, dl, OpVT, 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0), SDValue(signMask, 0)); 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == ISD::FABS) { 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT == MVT::f64) { 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT, 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0), SDValue(signMask, 0)); 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (OpVT == MVT::v2f64) { 836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman absConst, absConst); 839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *signMask = emitBuildVector(absVec.getNode()); 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT, 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0), SDValue(signMask, 0)); 842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == SPUISD::LDRESULT) { 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Custom select instructions for LDRESULT 845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Arg = N->getOperand(0); 847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Chain = N->getOperand(1); 848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Result; 849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT, 85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::Other, Arg, 85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getRC( VT.getSimpleVT()), Chain); 853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Opc == SPUISD::IndirectAddr) { 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Look at the operands: SelectCode() will catch the cases that aren't 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // specifically handled here. 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPUInstrInfo catches the following patterns: 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect (SPUhi ...), (SPUlo ...)) 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect $sp, imm) 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op1 = N->getOperand(1); 865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegisterSDNode *RN; 866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo) 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (Op0.getOpcode() == ISD::Register 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && RN->getReg() != SPU::R1))) { 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOpc = SPU::Ar32; 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[1] = Op1; 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op1.getOpcode() == ISD::Constant) { 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); 876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isInt<10>(CN->getSExtValue())) { 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOpc = SPU::AIr32; 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[1] = Op1; 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl, 88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getValueType(0), 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op1), 88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 0); 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = Op0; 887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n_ops = 2; 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (n_ops > 0) { 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->hasOneUse()) 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops); 896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectCode(N); 898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64 left shifts. The basic algorithm 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * is to fill the bottom two word slots with zeros so that zeros are shifted 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * in as the entire quadword is shifted left. 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * \note This code could also be used to implement v2i64 shl. 906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The shl operand 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param OpVT Op's machine value value type (doesn't need to be passed, but 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * makes life easier.) 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDNode with the entire instruction sequence 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode * 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); 91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpVT, (128 / OpVT.getSizeInBits())); 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShiftAmt = N->getOperand(1); 918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ShiftAmtVT = ShiftAmt.getValueType(); 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SelMaskVal; 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, 92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0, getRC(MVT::v2i64) ); 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal); 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT, 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(0, OpVT)); 929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(ZeroFill, 0), 931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), 932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(SelMask, 0)); 933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bits = unsigned(CN->getZExtValue()) & 7; 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (bytes > 0) { 939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT, 941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), 942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (bits > 0) { 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT, 948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue((Shift != 0 ? Shift : VecOp0), 0), 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Bytes = 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShiftAmt, 955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(3, ShiftAmtVT)); 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Bits = 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShiftAmt, 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(7, ShiftAmtVT)); 960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT, 962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT, 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(Shift, 0), SDValue(Bits, 0)); 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64 logical right shifts. 974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The shl operand 976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param OpVT Op's machine value value type (doesn't need to be passed, but 977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * makes life easier.) 978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDNode with the entire instruction sequence 979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode * 981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { 982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); 983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpVT, (128 / OpVT.getSizeInBits())); 985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShiftAmt = N->getOperand(1); 986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ShiftAmtVT = ShiftAmt.getValueType(); 987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *VecOp0, *Shift = 0; 988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, 99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0, getRC(MVT::v2i64) ); 992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bits = unsigned(CN->getZExtValue()) & 7; 996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (bytes > 0) { 998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT, 1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), 1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 1002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (bits > 0) { 1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT, 1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue((Shift != 0 ? Shift : VecOp0), 0), 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Bytes = 1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShiftAmt, 1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(3, ShiftAmtVT)); 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Bits = 1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShiftAmt, 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(7, ShiftAmtVT)); 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ensure that the shift amounts are negated! 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(Bytes, 0), 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(0, ShiftAmtVT)); 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(Bits, 0), 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(0, ShiftAmtVT)); 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT, 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT, 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(Shift, 0), SDValue(Bits, 0)); 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64 arithmetic right shifts. 1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The shl operand 1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param OpVT Op's machine value value type (doesn't need to be passed, but 1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * makes life easier.) 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDNode with the entire instruction sequence 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode * 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) { 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote Op0 to vector 105219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpVT, (128 / OpVT.getSizeInBits())); 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShiftAmt = N->getOperand(1); 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ShiftAmtVT = ShiftAmt.getValueType(); 1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *VecOp0 = 105919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 106019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VecVT, N->getOperand(0), getRC(MVT::v2i64)); 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SignRot = 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64, 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), SignRotAmt); 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *UpperHalfSign = 106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32)); 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *UpperHalfSignMask = 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0)); 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *UpperLowerMask = 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(0xff00ULL, MVT::i16)); 1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *UpperLowerSelect = 1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(UpperHalfSignMask, 0), 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(VecOp0, 0), 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(UpperLowerMask, 0)); 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Shift = 0; 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bits = unsigned(CN->getZExtValue()) & 7; 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (bytes > 0) { 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bytes = 31 - bytes; 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT, 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(UpperLowerSelect, 0), 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (bits > 0) { 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bits = 8 - bits; 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT, 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0), 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *NegShift = 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT)); 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT, 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0)); 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift = 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT, 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(Shift, 0), SDValue(NegShift, 0)); 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 111519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 111619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Do the necessary magic necessary to load a i64 constant 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT, 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(N); 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectI64Constant(CN->getZExtValue(), OpVT, dl); 1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2); 1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue i64vec = 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl); 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Here's where it gets interesting, because we have to parse out the 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // subtree handed back in i64vec: 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (i64vec.getOpcode() == ISD::BITCAST) { 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The degenerate case where the upper and lower bits in the splat are 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // identical: 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = i64vec.getOperand(0); 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceUses(i64vec, Op0); 114319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 114419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue(emitBuildVector(Op0.getNode()), 0), 114519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getRC(MVT::i64)); 1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (i64vec.getOpcode() == SPUISD::SHUFB) { 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhs = i64vec.getOperand(0); 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhs = i64vec.getOperand(1); 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue shufmask = i64vec.getOperand(2); 1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 115119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (lhs.getOpcode() == ISD::BITCAST) { 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceUses(lhs, lhs.getOperand(0)); 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhs = lhs.getOperand(0); 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() 1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? lhs.getNode() 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : emitBuildVector(lhs.getNode())); 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rhs.getOpcode() == ISD::BITCAST) { 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceUses(rhs, rhs.getOperand(0)); 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rhs = rhs.getOperand(0); 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() 1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? rhs.getNode() 1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : emitBuildVector(rhs.getNode())); 1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (shufmask.getOpcode() == ISD::BITCAST) { 1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceUses(shufmask, shufmask.getOperand(0)); 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman shufmask = shufmask.getOperand(0); 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? shufmask.getNode() 1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : emitBuildVector(shufmask.getNode())); 1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue shufNode = 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(lhsNode, 0), SDValue(rhsNode, 0), 1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(shufMaskNode, 0)); 1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(shufNode); 1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *SN = SelectCode(Dummy.getValue().getNode()); 1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SN == 0) SN = Dummy.getValue().getNode(); 118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OpVT, SDValue(SN, 0), getRC(MVT::i64)); 1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { 118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue(emitBuildVector(i64vec.getNode()), 0), 119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getRC(MVT::i64)); 1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" 1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "condition"); 1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// createSPUISelDag - This pass converts a legalized DAG into a 1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SPU-specific DAG, ready for instruction scheduling. 1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return new SPUDAGToDAGISel(TM); 1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1204