1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file implements the SPUTargetLowering class. 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUISelLowering.h" 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUTargetMachine.h" 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "SPUFrameLowering.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUMachineFunction.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Constants.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Function.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Intrinsics.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CallingConv.h" 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Type.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/CallingConvLower.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineRegisterInfo.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAG.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetOptions.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/VectorExtras.h" 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MathExtras.h" 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <map> 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Used in getTargetNodeName() below 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<unsigned, const char *> node_names; 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Byte offset of the preferred slot (counted from the MSB) 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int prefslotOffset(EVT VT) { 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int retval=0; 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VT==MVT::i1) retval=3; 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VT==MVT::i8) retval=3; 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VT==MVT::i16) retval=2; 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return retval; 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Expand a library call into an actual call DAG node 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*! 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \note 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman This code is taken from SelectionDAGLegalize, since it is not exposed as 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman part of the LLVM SelectionDAG API. 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExpandLibCall(RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG, 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned, SDValue &Hi, const SPUTargetLowering &TLI) { 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input chain to this libcall is the entry node of the function. 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalizing the call will automatically add the previous call to the 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // dependence. 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InChain = DAG.getEntryNode(); 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListTy Args; 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListEntry Entry; 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) { 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ArgVT = Op.getOperand(i).getValueType(); 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.Node = Op.getOperand(i); 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.Ty = ArgTy; 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.isSExt = isSigned; 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.isZExt = !isSigned; 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Args.push_back(Entry); 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy()); 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Splice the libcall in wherever FindInputOutputChains tells us to. 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *RetTy = 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getNode()->getValueType(0).getTypeForEVT(*DAG.getContext()); 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> CallInfo = 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 0, TLI.getLibcallCallingConv(LC), false, 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*isReturnValueUsed=*/true, 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee, Args, DAG, Op.getDebugLoc()); 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CallInfo.first; 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : TargetLowering(TM, new TargetLoweringObjectFileELF()), 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPUTM(TM) { 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use _setjmp/_longjmp instead of setjmp/longjmp. 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setUseUnderscoreSetJmp(true); 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setUseUnderscoreLongJmp(true); 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set RTLIB libcall names as used by SPU: 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLibcallName(RTLIB::DIV_F64, "__fast_divdf3"); 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set up the SPU's register classes: 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::i8, SPU::R8CRegisterClass); 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::i16, SPU::R16CRegisterClass); 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::i32, SPU::R32CRegisterClass); 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::i64, SPU::R64CRegisterClass); 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::f32, SPU::R32FPRegisterClass); 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::f64, SPU::R64FPRegisterClass); 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::i128, SPU::GPRCRegisterClass); 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has no sign or zero extended loads for i1, i8, i16: 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand); 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(MVT::i128, MVT::i64, Expand); 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(MVT::i128, MVT::i32, Expand); 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(MVT::i128, MVT::i16, Expand); 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(MVT::i128, MVT::i8, Expand); 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(MVT::f64, MVT::f32, Expand); 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU constant load actions are custom lowered: 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ConstantFP, MVT::f32, Legal); 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ConstantFP, MVT::f64, Custom); 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU's loads and stores have to be custom lowered: 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128; 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++sctype) { 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::SimpleValueType VT = (MVT::SimpleValueType)sctype; 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::LOAD, VT, Custom); 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::STORE, VT, Custom); 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::EXTLOAD, VT, Custom); 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::ZEXTLOAD, VT, Custom); 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setLoadExtAction(ISD::SEXTLOAD, VT, Custom); 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) { 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::SimpleValueType StoreVT = (MVT::SimpleValueType) stype; 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(VT, StoreVT, Expand); 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64; 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++sctype) { 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::SimpleValueType VT = (MVT::SimpleValueType) sctype; 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::LOAD, VT, Custom); 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::STORE, VT, Custom); 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) { 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::SimpleValueType StoreVT = (MVT::SimpleValueType) stype; 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTruncStoreAction(VT, StoreVT, Expand); 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the jumptable branches 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::BR_JT, MVT::Other, Expand); 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::BR_CC, MVT::Other, Expand); 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Custom lower SELECT_CC for most cases, but expand by default 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has no intrinsics for these particular operations: 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand); 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has no division/remainder instructions 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SREM, MVT::i8, Expand); 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UREM, MVT::i8, Expand); 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIV, MVT::i8, Expand); 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIV, MVT::i8, Expand); 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SREM, MVT::i16, Expand); 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UREM, MVT::i16, Expand); 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIV, MVT::i16, Expand); 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIV, MVT::i16, Expand); 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SREM, MVT::i32, Expand); 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UREM, MVT::i32, Expand); 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIV, MVT::i32, Expand); 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIV, MVT::i32, Expand); 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIVREM, MVT::i32, Expand); 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIVREM, MVT::i32, Expand); 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SREM, MVT::i64, Expand); 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UREM, MVT::i64, Expand); 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIV, MVT::i64, Expand); 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIV, MVT::i64, Expand); 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIVREM, MVT::i64, Expand); 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIVREM, MVT::i64, Expand); 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SREM, MVT::i128, Expand); 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UREM, MVT::i128, Expand); 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIV, MVT::i128, Expand); 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIV, MVT::i128, Expand); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIVREM, MVT::i128, Expand); 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIVREM, MVT::i128, Expand); 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We don't support sin/cos/sqrt/fmod 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FSIN , MVT::f64, Expand); 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FCOS , MVT::f64, Expand); 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FREM , MVT::f64, Expand); 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FSIN , MVT::f32, Expand); 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FCOS , MVT::f32, Expand); 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FREM , MVT::f32, Expand); 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // for f32!) 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FSQRT, MVT::f64, Expand); 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FSQRT, MVT::f32, Expand); 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::FMA, MVT::f64, Expand); 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::FMA, MVT::f32, Expand); 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU can do rotate right and left, so legalize it... but customize for i8 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // because instructions don't exist. 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Change from "expand" to appropriate type once ROTR is supported in 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // .td files. 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/); 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/); 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/); 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ROTL, MVT::i32, Legal); 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ROTL, MVT::i16, Legal); 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ROTL, MVT::i8, Custom); 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has no native version of shift left/right for i8 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SHL, MVT::i8, Custom); 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SRL, MVT::i8, Custom); 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SRA, MVT::i8, Custom); 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make these operations legal and handle them during instruction selection: 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SHL, MVT::i64, Legal); 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SRL, MVT::i64, Legal); 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SRA, MVT::i64, Legal); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Custom lower i8, i32 and i64 multiplications 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MUL, MVT::i8, Custom); 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MUL, MVT::i32, Legal); 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MUL, MVT::i64, Legal); 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand double-width multiplication 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: It would probably be reasonable to support some of these operations 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHU, MVT::i8, Expand); 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHS, MVT::i8, Expand); 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHU, MVT::i16, Expand); 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHS, MVT::i16, Expand); 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHU, MVT::i32, Expand); 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHS, MVT::i32, Expand); 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHU, MVT::i64, Expand); 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MULHS, MVT::i64, Expand); 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Need to custom handle (some) common i8, i64 math ops 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ADD, MVT::i8, Custom); 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ADD, MVT::i64, Legal); 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SUB, MVT::i8, Custom); 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SUB, MVT::i64, Legal); 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU does not have BSWAP. It does have i32 support CTLZ. 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CTPOP has to be custom lowered. 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::BSWAP, MVT::i32, Expand); 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::BSWAP, MVT::i64, Expand); 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTPOP, MVT::i8, Custom); 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTPOP, MVT::i16, Custom); 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTPOP, MVT::i32, Custom); 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTPOP, MVT::i64, Custom); 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTPOP, MVT::i128, Expand); 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTTZ , MVT::i8, Expand); 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTTZ , MVT::i16, Expand); 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTTZ , MVT::i32, Expand); 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTTZ , MVT::i64, Expand); 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTTZ , MVT::i128, Expand); 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTLZ , MVT::i8, Promote); 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTLZ , MVT::i16, Promote); 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTLZ , MVT::i32, Legal); 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTLZ , MVT::i64, Expand); 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::CTLZ , MVT::i128, Expand); 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has a version of select that implements (a&~c)|(b&c), just like 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // select ought to work: 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT, MVT::i8, Legal); 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT, MVT::i16, Legal); 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT, MVT::i32, Legal); 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT, MVT::i64, Legal); 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SETCC, MVT::i8, Legal); 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SETCC, MVT::i16, Legal); 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SETCC, MVT::i32, Legal); 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SETCC, MVT::i64, Legal); 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SETCC, MVT::f64, Custom); 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Custom lower i128 -> i64 truncates 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::TRUNCATE, MVT::i64, Custom); 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Custom lower i32/i64 -> i128 sign extend 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SIGN_EXTEND, MVT::i128, Custom); 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_SINT, MVT::i8, Promote); 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_UINT, MVT::i8, Promote); 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_UINT, MVT::i16, Promote); 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has a legal FP -> signed INT instruction for f32, but for f64, need 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to expand to a libcall, hence the custom lowering: 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_SINT, MVT::i64, Expand); 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_SINT, MVT::i128, Expand); 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_UINT, MVT::i128, Expand); 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FDIV on SPU requires custom lowering 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64: 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote); 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote); 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote); 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom); 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::BITCAST, MVT::i32, Legal); 35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::BITCAST, MVT::f32, Legal); 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::BITCAST, MVT::i64, Legal); 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::BITCAST, MVT::f64, Legal); 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We cannot sextinreg(i1). Expand to shifts. 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We want to legalize GlobalAddress and ConstantPool nodes into the 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // appropriate instructions to materialize the address. 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128; 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++sctype) { 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::SimpleValueType VT = (MVT::SimpleValueType)sctype; 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::GlobalAddress, VT, Custom); 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ConstantPool, VT, Custom); 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::JumpTable, VT, Custom); 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // VASTART needs to be custom lowered to use the VarArgsFrameIndex 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::VASTART , MVT::Other, Custom); 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use the default implementation. 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::VAARG , MVT::Other, Expand); 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::VACOPY , MVT::Other, Expand); 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::VAEND , MVT::Other, Expand); 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand); 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Cell SPU has instructions for converting between i64 and fp. 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // BUILD_PAIR can't be handled natively, and should be expanded to shl/or 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand); 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // First set operation action for all vector types to expand. Then we 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // will selectively turn on ones that can be effectively codegen'd. 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass); 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass); 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass); 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass); 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass); 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass); 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) { 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::SimpleValueType VT = (MVT::SimpleValueType)i; 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Set operation actions to legal types only. 40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isTypeLegal(VT)) continue; 40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // add/sub are legal for all supported vector VT's. 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ADD, VT, Legal); 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SUB, VT, Legal); 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // mul has to be custom lowered. 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::MUL, VT, Legal); 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::AND, VT, Legal); 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::OR, VT, Legal); 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::XOR, VT, Legal); 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::LOAD, VT, Custom); 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SELECT, VT, Legal); 41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setOperationAction(ISD::STORE, VT, Custom); 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // These operations need to be expanded: 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SDIV, VT, Expand); 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SREM, VT, Expand); 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UDIV, VT, Expand); 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::UREM, VT, Expand); 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Custom lower build_vector, constant pool spills, insert and 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // extract vector elements: 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::BUILD_VECTOR, VT, Custom); 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::ConstantPool, VT, Custom); 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom); 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom); 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom); 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom); 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::AND, MVT::v16i8, Custom); 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::OR, MVT::v16i8, Custom); 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::XOR, MVT::v16i8, Custom); 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom); 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setOperationAction(ISD::FDIV, MVT::v4f32, Legal); 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setBooleanContents(ZeroOrNegativeOneBooleanContent); 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); // FIXME: Is this correct? 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setStackPointerRegisterToSaveRestore(SPU::R1); 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We have target-specific dag combine patterns for the following nodes: 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTargetDAGCombine(ISD::ADD); 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTargetDAGCombine(ISD::ZERO_EXTEND); 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTargetDAGCombine(ISD::SIGN_EXTEND); 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setTargetDAGCombine(ISD::ANY_EXTEND); 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setMinFunctionAlignment(3); 45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman computeRegisterProperties(); 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set pre-RA register scheduler default to BURR, which produces slightly 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // better code than the default (could also be TDRR, but TargetLowering.h 461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // needs a mod to support that model): 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setSchedulingPreference(Sched::RegPressure); 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanconst char * 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::getTargetNodeName(unsigned Opcode) const 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (node_names.empty()) { 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG"; 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi"; 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo"; 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr"; 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr"; 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr"; 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT"; 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL"; 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB"; 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK"; 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB"; 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC"; 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT"; 48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman node_names[(unsigned) SPUISD::SHL_BITS] = "SPUISD::SHL_BITS"; 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman node_names[(unsigned) SPUISD::SHL_BYTES] = "SPUISD::SHL_BYTES"; 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL"; 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR"; 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT"; 487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] = 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "SPUISD::ROTBYTES_LEFT_BITS"; 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK"; 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB"; 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER"; 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER"; 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER"; 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<unsigned, const char *>::iterator i = node_names.find(Opcode); 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ((i != node_names.end()) ? i->second : 0); 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Return the Cell SPU's SETCC result type 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanEVT SPUTargetLowering::getSetCCResultType(EVT VT) const { 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // i8, i16 and i32 are valid SETCC result types 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::SimpleValueType retval; 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(VT.getSimpleVT().SimpleTy){ 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i1: 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman retval = MVT::i8; break; 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: 51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman retval = MVT::i16; break; 51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: 51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman retval = MVT::i32; 51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return retval; 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Calling convention code: 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUGenCallingConv.inc" 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// LowerOperation implementation 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Custom lower loads for CellSPU 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman within a 16-byte block, we have to rotate to extract the requested element. 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman For extending loads, we also want to ensure that the following sequence is 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitted, e.g. for MVT::f32 extending load to MVT::f64: 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman\verbatim 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman%1 v16i8,ch = load 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman%2 v16i8,ch = rotate %1 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman%3 v4f8, ch = bitconvert %2 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman%4 f32 = vec2perfslot %3 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman%5 f64 = fp_extend %4 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman\endverbatim 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman*/ 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoadSDNode *LN = cast<LoadSDNode>(Op); 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue the_chain = LN->getChain(); 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT InVT = LN->getMemoryVT(); 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OutVT = Op.getValueType(); 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::LoadExtType ExtType = LN->getExtensionType(); 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned alignment = LN->getAlignment(); 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int pso = prefslotOffset(InVT); 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT vecVT = InVT.isVector()? InVT: EVT::getVectorVT(*DAG.getContext(), InVT, 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (128 / InVT.getSizeInBits())); 56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // two sanity checks 56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert( LN->getAddressingMode() == ISD::UNINDEXED 56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && "we should get only UNINDEXED adresses"); 56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // clean aligned loads can be selected as-is 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (InVT.getSizeInBits() == 128 && (alignment%16) == 0) 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SDValue(); 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get pointerinfos to the memory chunk(s) that contain the data to load 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint64_t mpi_offset = LN->getPointerInfo().Offset; 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman mpi_offset -= mpi_offset%16; 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo lowMemPtr(LN->getPointerInfo().V, mpi_offset); 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo highMemPtr(LN->getPointerInfo().V, mpi_offset+16); 574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue result; 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue basePtr = LN->getBasePtr(); 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue rotate; 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((alignment%16) == 0) { 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ConstantSDNode *CN; 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Special cases for a known aligned load to simplify the base pointer 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // and the rotation amount: 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (basePtr.getOpcode() == ISD::ADD 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) { 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Known offset into basePtr 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t offset = CN->getSExtValue(); 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t rotamt = int64_t((offset & 0xf) - pso); 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rotamt < 0) 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotamt += 16; 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotate = DAG.getConstant(rotamt, MVT::i16); 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Simplify the base pointer for this case: 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = basePtr.getOperand(0); 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((offset & ~0xf) > 0) { 598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr, 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant((offset & ~0xf), PtrVT)); 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if ((basePtr.getOpcode() == SPUISD::AFormAddr) 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman || (basePtr.getOpcode() == SPUISD::IndirectAddr 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && basePtr.getOperand(0).getOpcode() == SPUISD::Hi 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) { 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Plain aligned a-form address: rotate into preferred slot 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Same for (SPUindirect (SPUhi ...), (SPUlo ...)) 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t rotamt = -pso; 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rotamt < 0) 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotamt += 16; 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotate = DAG.getConstant(rotamt, MVT::i16); 61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Offset the rotate amount by the basePtr and the preferred slot 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // byte offset 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t rotamt = -pso; 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rotamt < 0) 61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotamt += 16; 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rotate = DAG.getNode(ISD::ADD, dl, PtrVT, 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr, 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(rotamt, PtrVT)); 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Unaligned load: must be more pessimistic about addressing modes: 62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (basePtr.getOpcode() == ISD::ADD) { 62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFunction &MF = DAG.getMachineFunction(); 62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineRegisterInfo &RegInfo = MF.getRegInfo(); 62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass); 62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Flag; 62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op0 = basePtr.getOperand(0); 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op1 = basePtr.getOperand(1); 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isa<ConstantSDNode>(Op1)) { 63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Convert the (add <ptr>, <const>) to an indirect address contained 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // in a register. Note that this is done because we need to avoid 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // creating a 0(reg) d-form address due to the SPU's block loads. 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1); 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag); 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT); 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Convert the (add <arg1>, <arg2>) to an indirect address, which 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // will likely be lowered as a reg(reg) x-form address. 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1); 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, PtrVT)); 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Offset the rotate amount by the basePtr and the preferred slot 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // byte offset 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotate = DAG.getNode(ISD::ADD, dl, PtrVT, 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(-pso, PtrVT)); 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do the load as a i128 to allow possible shifting 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue low = DAG.getLoad(MVT::i128, dl, the_chain, basePtr, 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowMemPtr, 66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LN->isVolatile(), LN->isNonTemporal(), 16); 66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // When the size is not greater than alignment we get all data with just 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // one load 66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (alignment >= InVT.getSizeInBits()/8) { 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update the chain 66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman the_chain = low.getValue(1); 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Rotate into the preferred slot: 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, MVT::i128, 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman low.getValue(0), rotate); 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert the loaded v16i8 vector to the appropriate vector type 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // specified by the operand: 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT vecVT = EVT::getVectorVT(*DAG.getContext(), 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InVT, (128 / InVT.getSizeInBits())); 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT, 67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, vecVT, result)); 67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // When alignment is less than the size, we might need (known only at 68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // run-time) two loads 68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // TODO: if the memory address is composed only from constants, we have 68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // extra kowledge, and might avoid the second load 68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else { 68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // storage position offset from lower 16 byte aligned memory chunk 68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue offset = DAG.getNode(ISD::AND, dl, MVT::i32, 68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, DAG.getConstant( 0xf, MVT::i32 ) ); 68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // get a registerfull of ones. (this implementation is a workaround: LLVM 68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // cannot handle 128 bit signed int constants) 69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ones = DAG.getConstant(-1, MVT::v4i32 ); 69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ones = DAG.getNode(ISD::BITCAST, dl, MVT::i128, ones); 69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue high = DAG.getLoad(MVT::i128, dl, the_chain, 69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::ADD, dl, PtrVT, 69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(16, PtrVT)), 69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman highMemPtr, 69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LN->isVolatile(), LN->isNonTemporal(), 16); 69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman the_chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, low.getValue(1), 70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman high.getValue(1)); 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Shift the (possible) high part right to compensate the misalignemnt. 70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // if there is no highpart (i.e. value is i64 and offset is 4), this 70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // will zero out the high value. 70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman high = DAG.getNode(SPUISD::SRL_BYTES, dl, MVT::i128, high, 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SUB, dl, MVT::i32, 70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant( 16, MVT::i32), 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman offset 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman )); 71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Shift the low similarly 71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // TODO: add SPUISD::SHL_BYTES 71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman low = DAG.getNode(SPUISD::SHL_BYTES, dl, MVT::i128, low, offset ); 71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Merge the two parts 71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = DAG.getNode(ISD::BITCAST, dl, vecVT, 71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::OR, dl, MVT::i128, low, high)); 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!InVT.isVector()) { 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT, result ); 72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Handle extending loads by extending the scalar result: 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ExtType == ISD::SEXTLOAD) { 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(ISD::SIGN_EXTEND, dl, OutVT, result); 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (ExtType == ISD::ZEXTLOAD) { 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(ISD::ZERO_EXTEND, dl, OutVT, result); 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (ExtType == ISD::EXTLOAD) { 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NewOpc = ISD::ANY_EXTEND; 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OutVT.isFloatingPoint()) 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOpc = ISD::FP_EXTEND; 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(NewOpc, dl, OutVT, result); 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDVTList retvts = DAG.getVTList(OutVT, MVT::Other); 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue retops[2] = { 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result, 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman the_chain 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(SPUISD::LDRESULT, dl, retvts, 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman retops, sizeof(retops) / sizeof(retops[0])); 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return result; 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Custom lower stores for CellSPU 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman All CellSPU stores are aligned to 16-byte boundaries, so for elements 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman within a 16-byte block, we have to generate a shuffle to insert the 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman requested element into its place, then store the resulting block. 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StoreSDNode *SN = cast<StoreSDNode>(Op); 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Value = SN->getValue(); 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Value.getValueType(); 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT()); 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned alignment = SN->getAlignment(); 76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue result; 76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT vecVT = StVT.isVector()? StVT: EVT::getVectorVT(*DAG.getContext(), StVT, 76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (128 / StVT.getSizeInBits())); 76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get pointerinfos to the memory chunk(s) that contain the data to load 76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint64_t mpi_offset = SN->getPointerInfo().Offset; 77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman mpi_offset -= mpi_offset%16; 77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo lowMemPtr(SN->getPointerInfo().V, mpi_offset); 77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo highMemPtr(SN->getPointerInfo().V, mpi_offset+16); 77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // two sanity checks 77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert( SN->getAddressingMode() == ISD::UNINDEXED 77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && "we should get only UNINDEXED adresses"); 77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // clean aligned loads can be selected as-is 77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (StVT.getSizeInBits() == 128 && (alignment%16) == 0) 78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SDValue(); 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue alignLoadVec; 78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue basePtr = SN->getBasePtr(); 78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue the_chain = SN->getChain(); 78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue insertEltOffs; 78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((alignment%16) == 0) { 78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ConstantSDNode *CN; 78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Special cases for a known aligned load to simplify the base pointer 79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // and insertion byte: 79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (basePtr.getOpcode() == ISD::ADD 79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) { 79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Known offset into basePtr 79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t offset = CN->getSExtValue(); 79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Simplify the base pointer for this case: 79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = basePtr.getOperand(0); 79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant((offset & 0xf), PtrVT)); 80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((offset & ~0xf) > 0) { 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr, 80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant((offset & ~0xf), PtrVT)); 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Otherwise, assume it's at byte 0 of basePtr 80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, PtrVT)); 81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr, 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0, PtrVT)); 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Unaligned load: must be more pessimistic about addressing modes: 81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (basePtr.getOpcode() == ISD::ADD) { 81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFunction &MF = DAG.getMachineFunction(); 82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineRegisterInfo &RegInfo = MF.getRegInfo(); 82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass); 82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Flag; 82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op0 = basePtr.getOperand(0); 82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op1 = basePtr.getOperand(1); 82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isa<ConstantSDNode>(Op1)) { 82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Convert the (add <ptr>, <const>) to an indirect address contained 82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // in a register. Note that this is done because we need to avoid 83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // creating a 0(reg) d-form address due to the SPU's block loads. 83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1); 83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag); 83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT); 83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Convert the (add <arg1>, <arg2>) to an indirect address, which 83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // will likely be lowered as a reg(reg) x-form address. 83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1); 83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, PtrVT)); 84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Insertion point is solely determined by basePtr's contents 84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman insertEltOffs = DAG.getNode(ISD::ADD, dl, PtrVT, 84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman basePtr, 84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, PtrVT)); 84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load the lower part of the memory to which to store. 85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue low = DAG.getLoad(vecVT, dl, the_chain, basePtr, 85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowMemPtr, SN->isVolatile(), SN->isNonTemporal(), 16); 85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // if we don't need to store over the 16 byte boundary, one store suffices 85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (alignment >= StVT.getSizeInBits()/8) { 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update the chain 85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman the_chain = low.getValue(1); 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadSDNode *LN = cast<LoadSDNode>(low); 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue theValue = SN->getValue(); 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StVT != VT 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && (theValue.getOpcode() == ISD::AssertZext 865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || theValue.getOpcode() == ISD::AssertSext)) { 866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Drill down and get the value for zero- and sign-extended 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // quantities 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman theValue = theValue.getOperand(0); 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the base pointer is already a D-form address, then just create 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // a new D-form address with a slot offset and the orignal base pointer. 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise generate a D-form address with the slot offset relative 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to the stack pointer, which is always aligned. 875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if !defined(NDEBUG) 876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "CellSPU LowerSTORE: basePtr = "; 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman basePtr.getNode()->dump(&DAG); 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\n"; 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue insertEltOp = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, vecVT, 88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman insertEltOffs); 88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue vectorizeOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, vecVT, 88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman theValue); 88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(SPUISD::SHUFB, dl, vecVT, 88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman vectorizeOp, low, 89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::v4i32, insertEltOp)); 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getStore(the_chain, dl, result, basePtr, 89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowMemPtr, 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LN->isVolatile(), LN->isNonTemporal(), 89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16); 89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // do the store when it might cross the 16 byte memory access boundary. 90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else { 90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // TODO issue a warning if SN->isVolatile()== true? This is likely not 90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // what the user wanted. 90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // address offset from nearest lower 16byte alinged address 90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue offset = DAG.getNode(ISD::AND, dl, MVT::i32, 90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SN->getBasePtr(), 90719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0xf, MVT::i32)); 90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 16 - offset 90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue offset_compl = DAG.getNode(ISD::SUB, dl, MVT::i32, 91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant( 16, MVT::i32), 91119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman offset); 91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 16 - sizeof(Value) 91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue surplus = DAG.getNode(ISD::SUB, dl, MVT::i32, 91419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant( 16, MVT::i32), 91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant( VT.getSizeInBits()/8, 91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::i32)); 91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // get a registerfull of ones 91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ones = DAG.getConstant(-1, MVT::v4i32); 91919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ones = DAG.getNode(ISD::BITCAST, dl, MVT::i128, ones); 92019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 92119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Create the 128 bit masks that have ones where the data to store is 92219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // located. 92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue lowmask, himask; 92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // if the value to store don't fill up the an entire 128 bits, zero 92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // out the last bits of the mask so that only the value we want to store 92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // is masked. 92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // this is e.g. in the case of store i32, align 2 92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!VT.isVector()){ 92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, Value); 93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowmask = DAG.getNode(SPUISD::SRL_BYTES, dl, MVT::i128, ones, surplus); 93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowmask = DAG.getNode(SPUISD::SHL_BYTES, dl, MVT::i128, lowmask, 93219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman surplus); 93319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value = DAG.getNode(ISD::BITCAST, dl, MVT::i128, Value); 93419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value = DAG.getNode(ISD::AND, dl, MVT::i128, Value, lowmask); 93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 93619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 93719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else { 93819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowmask = ones; 93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value = DAG.getNode(ISD::BITCAST, dl, MVT::i128, Value); 94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 94119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // this will zero, if there are no data that goes to the high quad 94219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman himask = DAG.getNode(SPUISD::SHL_BYTES, dl, MVT::i128, lowmask, 94319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman offset_compl); 94419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowmask = DAG.getNode(SPUISD::SRL_BYTES, dl, MVT::i128, lowmask, 94519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman offset); 94619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 94719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load in the old data and zero out the parts that will be overwritten with 94819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the new data to store. 94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue hi = DAG.getLoad(MVT::i128, dl, the_chain, 95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::ADD, dl, PtrVT, basePtr, 95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant( 16, PtrVT)), 95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman highMemPtr, 95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SN->isVolatile(), SN->isNonTemporal(), 16); 95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman the_chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, low.getValue(1), 95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman hi.getValue(1)); 95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 95719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman low = DAG.getNode(ISD::AND, dl, MVT::i128, 95819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode( ISD::BITCAST, dl, MVT::i128, low), 95919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode( ISD::XOR, dl, MVT::i128, lowmask, ones)); 96019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman hi = DAG.getNode(ISD::AND, dl, MVT::i128, 96119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode( ISD::BITCAST, dl, MVT::i128, hi), 96219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode( ISD::XOR, dl, MVT::i128, himask, ones)); 96319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 96419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Shift the Value to store into place. rlow contains the parts that go to 96519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the lower memory chunk, rhi has the parts that go to the upper one. 96619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue rlow = DAG.getNode(SPUISD::SRL_BYTES, dl, MVT::i128, Value, offset); 96719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rlow = DAG.getNode(ISD::AND, dl, MVT::i128, rlow, lowmask); 96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue rhi = DAG.getNode(SPUISD::SHL_BYTES, dl, MVT::i128, Value, 96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman offset_compl); 97019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Merge the old data and the new data and store the results 97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Need to convert vectors here to integer as 'OR'ing floats assert 97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rlow = DAG.getNode(ISD::OR, dl, MVT::i128, 97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, MVT::i128, low), 97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, MVT::i128, rlow)); 97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rhi = DAG.getNode(ISD::OR, dl, MVT::i128, 97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, MVT::i128, hi), 97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, MVT::i128, rhi)); 97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman low = DAG.getStore(the_chain, dl, rlow, basePtr, 98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman lowMemPtr, 98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SN->isVolatile(), SN->isNonTemporal(), 16); 98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman hi = DAG.getStore(the_chain, dl, rhi, 98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::ADD, dl, PtrVT, basePtr, 98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant( 16, PtrVT)), 98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman highMemPtr, 98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SN->isVolatile(), SN->isNonTemporal(), 16); 98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, low.getValue(0), 98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman hi.getValue(0)); 990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return result; 993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Generate the address of a constant pool entry. 996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { 998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = Op.getValueType(); 999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Constant *C = CP->getConstVal(); 1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); 1002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, PtrVT); 1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetMachine &TM = DAG.getTarget(); 1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME there is no actual debug info here 1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TM.getRelocationModel() == Reloc::Static) { 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->usingLargeMem()) { 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Just return the SDValue with the constant pool address in it. 1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, CPI, Zero); 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, CPI, Zero); 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, CPI, Zero); 1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo); 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("LowerConstantPool: Relocation model other than static" 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " not supported."); 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Alternate entry point for generating the address of a constant pool entry 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) { 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl()); 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = Op.getValueType(); 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, PtrVT); 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetMachine &TM = DAG.getTarget(); 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME there is no actual debug info here 1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TM.getRelocationModel() == Reloc::Static) { 1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->usingLargeMem()) { 1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, JTI, Zero); 1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, JTI, Zero); 1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, JTI, Zero); 1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo); 1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("LowerJumpTable: Relocation model other than static" 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " not supported."); 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { 1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = Op.getValueType(); 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const GlobalValue *GV = GSDN->getGlobal(); 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue GA = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(), 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PtrVT, GSDN->getOffset()); 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetMachine &TM = DAG.getTarget(); 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, PtrVT); 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME there is no actual debug info here 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TM.getRelocationModel() == Reloc::Static) { 1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->usingLargeMem()) { 1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, GA, Zero); 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, GA, Zero); 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, GA, Zero); 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo); 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("LowerGlobalAddress: Relocation model other than static" 1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "not supported."); 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Custom lower double precision floating point constants 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerConstantFP(SDValue Op, SelectionDAG &DAG) { 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME there is no actual debug info here 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::f64) { 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode()); 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((FP != 0) && 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "LowerConstantFP: Node is not ConstantFPSDNode"); 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble()); 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue T = DAG.getConstant(dbits, MVT::i64); 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T); 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, 110019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, MVT::v2f64, Tvec)); 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::LowerFormalArguments(SDValue Chain, 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallingConv::ID CallConv, bool isVarArg, 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<ISD::InputArg> 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &Ins, 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl, SelectionDAG &DAG, 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue> &InVals) 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const { 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFunction &MF = DAG.getMachineFunction(); 1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFrameInfo *MFI = MF.getFrameInfo(); 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineRegisterInfo &RegInfo = MF.getRegInfo(); 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPUFunctionInfo *FuncInfo = MF.getInfo<SPUFunctionInfo>(); 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 112019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ArgOffset = SPUFrameLowering::minStackSize(); 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ArgRegIdx = 0; 112219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned StackSlotSize = SPUFrameLowering::stackSlotSize(); 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<CCValAssign, 16> ArgLocs; 112719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 112819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getTargetMachine(), ArgLocs, *DAG.getContext()); 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: allow for other calling conventions 1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCInfo.AnalyzeFormalArguments(Ins, CCC_SPU); 1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add DAG nodes to load the arguments or copy them out of registers. 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ObjectVT = Ins[ArgNo].VT; 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ObjSize = ObjectVT.getSizeInBits()/8; 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ArgVal; 1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCValAssign &VA = ArgLocs[ArgNo]; 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VA.isRegLoc()) { 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *ArgRegClass; 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (ObjectVT.getSimpleVT().SimpleTy) { 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("LowerFormalArguments Unhandled argument type: " + 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Twine(ObjectVT.getEVTString())); 1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::R8CRegClass; 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: 1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::R16CRegClass; 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::R32CRegClass; 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::R64CRegClass; 1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i128: 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::GPRCRegClass; 1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::R32FPRegClass; 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: 1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::R64FPRegClass; 1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2f64: 1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4f32: 1169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2i64: 1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4i32: 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v8i16: 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v16i8: 1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgRegClass = &SPU::VECREGRegClass; 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass); 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegInfo.addLiveIn(VA.getLocReg(), VReg); 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT); 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++ArgRegIdx; 1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We need to load the argument to a virtual register if we determined 1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // above that we ran out of physical registers of the appropriate type 1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // or we're forced to do vararg 1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = MFI->CreateFixedObject(ObjSize, ArgOffset, true); 1186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue FIN = DAG.getFrameIndex(FI, PtrVT); 118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo(), 118819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgOffset += StackSlotSize; 1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InVals.push_back(ArgVal); 1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update the chain 1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = ArgVal.getOperand(0); 1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // vararg handling: 1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isVarArg) { 119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: we should be able to query the argument registers from 120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // tablegen generated code. 1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static const unsigned ArgRegs[] = { 1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R3, SPU::R4, SPU::R5, SPU::R6, SPU::R7, SPU::R8, SPU::R9, 1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R10, SPU::R11, SPU::R12, SPU::R13, SPU::R14, SPU::R15, SPU::R16, 1204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R17, SPU::R18, SPU::R19, SPU::R20, SPU::R21, SPU::R22, SPU::R23, 1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R24, SPU::R25, SPU::R26, SPU::R27, SPU::R28, SPU::R29, SPU::R30, 1206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R31, SPU::R32, SPU::R33, SPU::R34, SPU::R35, SPU::R36, SPU::R37, 1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R38, SPU::R39, SPU::R40, SPU::R41, SPU::R42, SPU::R43, SPU::R44, 1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R45, SPU::R46, SPU::R47, SPU::R48, SPU::R49, SPU::R50, SPU::R51, 1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R52, SPU::R53, SPU::R54, SPU::R55, SPU::R56, SPU::R57, SPU::R58, 1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R59, SPU::R60, SPU::R61, SPU::R62, SPU::R63, SPU::R64, SPU::R65, 1211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R66, SPU::R67, SPU::R68, SPU::R69, SPU::R70, SPU::R71, SPU::R72, 1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPU::R73, SPU::R74, SPU::R75, SPU::R76, SPU::R77, SPU::R78, SPU::R79 1213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 1214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // size of ArgRegs array 1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumArgRegs = 77; 1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We will spill (79-3)+1 registers to the stack 1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 79-3+1> MemOps; 1219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create the frame slot 1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) { 1222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FuncInfo->setVarArgsFrameIndex( 1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->CreateFixedObject(StackSlotSize, ArgOffset, true)); 1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); 122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned VReg = MF.addLiveIn(ArgRegs[ArgRegIdx], &SPU::VECREGRegClass); 1226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ArgVal = DAG.getRegister(VReg, MVT::v16i8); 122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Store = DAG.getStore(Chain, dl, ArgVal, FIN, MachinePointerInfo(), 1228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 1229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = Store.getOperand(0); 1230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemOps.push_back(Store); 1231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Increment address by stack slot size for the next stored argument 1233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgOffset += StackSlotSize; 1234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MemOps.empty()) 1236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &MemOps[0], MemOps.size()); 1238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Chain; 1241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// isLSAAddress - Return the immediate to use if the specified 1244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// value is representable as a LSA address. 1245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) { 1246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op); 1247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!C) return 0; 1248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Addr = C->getZExtValue(); 1250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero. 1251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (Addr << 14 >> 14) != Addr) 1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; // Top 14 bits have to be sext of immediate. 1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode(); 1255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee, 1259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallingConv::ID CallConv, bool isVarArg, 1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool &isTailCall, 1261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<ISD::OutputArg> &Outs, 1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<SDValue> &OutVals, 1263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<ISD::InputArg> &Ins, 1264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl, SelectionDAG &DAG, 1265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue> &InVals) const { 1266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CellSPU target does not yet support tail call optimization. 1267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isTailCall = false; 1268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SPUSubtarget *ST = SPUTM.getSubtargetImpl(); 1270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumOps = Outs.size(); 127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned StackSlotSize = SPUFrameLowering::stackSlotSize(); 1272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<CCValAssign, 16> ArgLocs; 127419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 127519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getTargetMachine(), ArgLocs, *DAG.getContext()); 1276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: allow for other calling conventions 1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCInfo.AnalyzeCallOperands(Outs, CCC_SPU); 127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const unsigned NumArgRegs = ArgLocs.size(); 1280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Handy pointer type 1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 1284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set up a copy of the stack pointer for use loading and storing any 1286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // arguments that may not fit in the registers available for argument 1287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // passing. 1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32); 1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Figure out which arguments are going to go in registers, and which in 1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // memory. 129219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ArgOffset = SPUFrameLowering::minStackSize(); // Just below [LR] 1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ArgRegIdx = 0; 1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Keep track of registers passing arguments 1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<std::pair<unsigned, SDValue> > RegsToPass; 1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // And the arguments passed on the stack 1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> MemOpChains; 1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (; ArgRegIdx != NumOps; ++ArgRegIdx) { 1301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Arg = OutVals[ArgRegIdx]; 1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCValAssign &VA = ArgLocs[ArgRegIdx]; 1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // PtrOff will be used to store the current argument to the stack if a 1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // register cannot be found for it. 1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); 1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff); 1308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Arg.getValueType().getSimpleVT().SimpleTy) { 1310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected ValueType for argument!"); 1311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: 1312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: 1313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 1314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 1315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i128: 1316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: 1317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: 1318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2i64: 1319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2f64: 1320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4f32: 1321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4i32: 1322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v8i16: 1323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v16i8: 1324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ArgRegIdx != NumArgRegs) { 1325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 1326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 132719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 132819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), 1329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0)); 1330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArgOffset += StackSlotSize; 1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Accumulate how many bytes are to be pushed on the stack, including the 1337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // linkage area, and parameter passing area. According to the SPU ABI, 1338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // we minimally need space for [LR] and [SP]. 133919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumStackBytes = ArgOffset - SPUFrameLowering::minStackSize(); 1340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Insert a call sequence start 1342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes, 1343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman true)); 1344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MemOpChains.empty()) { 1346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Adjust the stack pointer for the stack arguments. 1347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &MemOpChains[0], MemOpChains.size()); 1349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Build a sequence of copy-to-reg nodes chained together with token chain 1352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and flag operands which copy the outgoing args into the appropriate regs. 1353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InFlag; 1354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 1355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 1356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegsToPass[i].second, InFlag); 1357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InFlag = Chain.getValue(1); 1358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops; 1361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CallOpc = SPUISD::CALL; 1362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every 1364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 1365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // node so that legalize doesn't hack it. 1366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 1367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const GlobalValue *GV = G->getGlobal(); 1368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT CalleeVT = Callee.getValueType(); 1369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, PtrVT); 1370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue GA = DAG.getTargetGlobalAddress(GV, dl, CalleeVT); 1371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->usingLargeMem()) { 1373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Turn calls to targets that are defined (i.e., have bodies) into BRSL 1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // style calls, otherwise, external symbols are BRASL calls. This assumes 1375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // that declared/defined symbols are in the same compilation unit and can 1376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // be reached through PC-relative jumps. 1377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: 1379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This may be an unsafe assumption for JIT and really large compilation 1380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // units. 1381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (GV->isDeclaration()) { 1382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, GA, Zero); 1383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee = DAG.getNode(SPUISD::PCRelAddr, dl, CalleeVT, GA, Zero); 1385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // "Large memory" mode: Turn all calls into indirect calls with a X-form 1388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // address pairs: 1389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, GA, Zero); 1390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { 1392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT CalleeVT = Callee.getValueType(); 1393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, PtrVT); 1394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(), 1395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee.getValueType()); 1396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->usingLargeMem()) { 1398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, ExtSym, Zero); 1399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, ExtSym, Zero); 1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) { 1403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is an absolute destination address that appears to be a legal 1404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // local store address, use the munged value. 1405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee = SDValue(Dest, 0); 1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(Chain); 1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(Callee); 1410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add argument registers to the end of the list so that they are known live 1412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // into the call. 1413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 1414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(DAG.getRegister(RegsToPass[i].first, 1415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegsToPass[i].second.getValueType())); 1416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (InFlag.getNode()) 1418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(InFlag); 1419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Returns a chain and a flag for retval copy to use. 142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Glue), 1421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &Ops[0], Ops.size()); 1422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InFlag = Chain.getValue(1); 1423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true), 1425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(0, true), InFlag); 1426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Ins.empty()) 1427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InFlag = Chain.getValue(1); 1428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the function returns void, just return the chain. 1430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Ins.empty()) 1431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Chain; 1432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 143319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Now handle the return value(s) 143419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<CCValAssign, 16> RVLocs; 143519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CCState CCRetInfo(CallConv, isVarArg, DAG.getMachineFunction(), 143619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getTargetMachine(), RVLocs, *DAG.getContext()); 143719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CCRetInfo.AnalyzeCallResult(Ins, CCC_SPU); 143819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the call has results, copy the values out of the ret val registers. 144119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != RVLocs.size(); ++i) { 144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CCValAssign VA = RVLocs[i]; 144319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 144419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(), 144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman InFlag); 144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Chain = Val.getValue(1); 144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman InFlag = Val.getValue(2); 144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman InVals.push_back(Val); 144919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Chain; 1452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 1455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::LowerReturn(SDValue Chain, 1456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallingConv::ID CallConv, bool isVarArg, 1457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<ISD::OutputArg> &Outs, 1458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<SDValue> &OutVals, 1459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl, SelectionDAG &DAG) const { 1460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<CCValAssign, 16> RVLocs; 146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getTargetMachine(), RVLocs, *DAG.getContext()); 1464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCInfo.AnalyzeReturn(Outs, RetCC_SPU); 1465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is the first return lowered for this function, add the regs to the 1467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // liveout set for the function. 1468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 1469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != RVLocs.size(); ++i) 1470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 1471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Flag; 1474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Copy the result values into the output registers. 1476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != RVLocs.size(); ++i) { 1477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCValAssign &VA = RVLocs[i]; 1478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(VA.isRegLoc() && "Can only return in registers!"); 1479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 1480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutVals[i], Flag); 1481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Flag = Chain.getValue(1); 1482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Flag.getNode()) 1485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 1486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain); 1488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 1492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Vector related lowering: 1493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 1494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic ConstantSDNode * 1496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumangetVecImm(SDNode *N) { 1497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue OpVal(0, 0); 1498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check to see if this buildvec has a single non-undef value in its elements. 1500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 1501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue; 1502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVal.getNode() == 0) 1503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpVal = N->getOperand(i); 1504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (OpVal != N->getOperand(i)) 1505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 1506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVal.getNode() != 0) { 1509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) { 1510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CN; 1511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 1515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_vec_i18imm - Test if this vector is a vector filled with the same value 1518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and the value fits into an unsigned 18-bit constant, and if so, return the 1519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constant 1520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG, 1521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ValueType) { 1522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t Value = CN->getZExtValue(); 1524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ValueType == MVT::i64) { 1525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t UValue = CN->getZExtValue(); 1526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t upper = uint32_t(UValue >> 32); 1527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t lower = uint32_t(UValue); 1528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (upper != lower) 1529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Value = Value >> 32; 1531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Value <= 0x3ffff) 1533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant(Value, ValueType); 1534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_vec_i16imm - Test if this vector is a vector filled with the same value 1540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and the value fits into a signed 16-bit constant, and if so, return the 1541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constant 1542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG, 1543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ValueType) { 1544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t Value = CN->getSExtValue(); 1546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ValueType == MVT::i64) { 1547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t UValue = CN->getZExtValue(); 1548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t upper = uint32_t(UValue >> 32); 1549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t lower = uint32_t(UValue); 1550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (upper != lower) 1551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Value = Value >> 32; 1553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) { 1555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant(Value, ValueType); 1556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_vec_i10imm - Test if this vector is a vector filled with the same value 1563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and the value fits into a signed 10-bit constant, and if so, return the 1564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constant 1565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG, 1566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ValueType) { 1567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t Value = CN->getSExtValue(); 1569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ValueType == MVT::i64) { 1570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t UValue = CN->getZExtValue(); 1571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t upper = uint32_t(UValue >> 32); 1572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t lower = uint32_t(UValue); 1573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (upper != lower) 1574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Value = Value >> 32; 1576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isInt<10>(Value)) 1578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant(Value, ValueType); 1579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_vec_i8imm - Test if this vector is a vector filled with the same value 1585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and the value fits into a signed 8-bit constant, and if so, return the 1586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constant. 1587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// @note: The incoming vector is v16i8 because that's the only way we can load 1589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constant vectors. Thus, we test to see if the upper and lower bytes are the 1590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// same value. 1591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG, 1592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ValueType) { 1593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Value = (int) CN->getZExtValue(); 1595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ValueType == MVT::i16 1596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && Value <= 0xffff /* truncated from uint64_t */ 1597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && ((short) Value >> 8) == ((short) Value & 0xff)) 1598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant(Value & 0xff, ValueType); 1599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (ValueType == MVT::i8 1600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && (Value & 0xff) == Value) 1601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant(Value, ValueType); 1602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value 1608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and the value fits into a signed 16-bit constant, and if so, return the 1609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constant 1610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG, 1611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ValueType) { 1612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t Value = CN->getZExtValue(); 1614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((ValueType == MVT::i32 1615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && ((unsigned) Value & 0xffff0000) == (unsigned) Value) 1616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value)) 1617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant(Value >> 16, ValueType); 1618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_v4i32_imm - Catch-all for general 32-bit constant vectors 1624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) { 1625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32); 1627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// get_v4i32_imm - Catch-all for general 64-bit constant vectors 1633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) { 1634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = getVecImm(N)) { 1635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64); 1636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Lower a BUILD_VECTOR instruction creatively: 1642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 1643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { 1644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 1645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = VT.getVectorElementType(); 1646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(Op.getNode()); 1648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerBUILD_VECTOR"); 1649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned minSplatBits = EltVT.getSizeInBits(); 1650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (minSplatBits < 16) 1652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman minSplatBits = 16; 1653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt APSplatBits, APSplatUndef; 1655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SplatBitSize; 1656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasAnyUndefs; 1657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize, 1659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HasAnyUndefs, minSplatBits) 1660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || minSplatBits < SplatBitSize) 1661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); // Wasn't a constant vector or splat exceeded min 1662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t SplatBits = APSplatBits.getZExtValue(); 1664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.getSimpleVT().SimpleTy) { 1666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = " + 1668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Twine(VT.getEVTString())); 1669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 1670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4f32: { 1671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t Value32 = uint32_t(SplatBits); 1672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(SplatBitSize == 32 1673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && "LowerBUILD_VECTOR: Unexpected floating point vector element."); 1674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: pretend the constant is an integer. LLVM won't load FP constants 1675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue T = DAG.getConstant(Value32, MVT::i32); 167619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, 1677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, T,T,T,T)); 1678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2f64: { 1681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t f64val = uint64_t(SplatBits); 1682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(SplatBitSize == 64 1683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes."); 1684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: pretend the constant is an integer. LLVM won't load FP constants 1685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue T = DAG.getConstant(f64val, MVT::i64); 168619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, MVT::v2f64, 1687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T)); 1688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v16i8: { 1691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 8-bit constants have to be expanded to 16-bits 1692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned short Value16 = SplatBits /* | (SplatBits << 8) */; 1693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops; 1694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.assign(8, DAG.getConstant(Value16, MVT::i16)); 169619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, VT, 1697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i16, &Ops[0], Ops.size())); 1698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v8i16: { 1700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned short Value16 = SplatBits; 1701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue T = DAG.getConstant(Value16, EltVT); 1702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops; 1703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.assign(8, T); 1705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); 1706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4i32: { 1708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType()); 1709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T); 1710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2i64: { 1712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl); 1713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 1720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 1722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPU::LowerV2I64Splat(EVT OpVT, SelectionDAG& DAG, uint64_t SplatVal, 1723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 1724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t upper = uint32_t(SplatVal >> 32); 1725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint32_t lower = uint32_t(SplatVal); 1726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (upper == lower) { 1728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Magic constant that can be matched by IL, ILA, et. al. 1729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Val = DAG.getTargetConstant(upper, MVT::i32); 173019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, OpVT, 1731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Val, Val, Val, Val)); 1733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool upper_special, lower_special; 1735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: This code creates common-case shuffle masks that can be easily 1737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // detected as common expressions. It is not attempting to create highly 1738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // specialized masks to replace any and all 0's, 0xff's and 0x80's. 1739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Detect if the upper or lower half is a special shuffle mask pattern: 1741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000); 1742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000); 1743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Both upper and lower are special, lower to a constant pool load: 1745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (lower_special && upper_special) { 1746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SplatValCN = DAG.getConstant(SplatVal, MVT::i64); 1747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 1748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplatValCN, SplatValCN); 1749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LO32; 1752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HI32; 1753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16> ShufBytes; 1754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Result; 1755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create lower vector if not a special pattern 1757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!lower_special) { 1758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LO32C = DAG.getConstant(lower, MVT::i32); 175919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LO32 = DAG.getNode(ISD::BITCAST, dl, OpVT, 1760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LO32C, LO32C, LO32C, LO32C)); 1762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create upper vector if not a special pattern 1765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!upper_special) { 1766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HI32C = DAG.getConstant(upper, MVT::i32); 176719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HI32 = DAG.getNode(ISD::BITCAST, dl, OpVT, 1768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HI32C, HI32C, HI32C, HI32C)); 1770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If either upper or lower are special, then the two input operands are 1773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the same (basically, one of them is a "don't care") 1774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (lower_special) 1775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LO32 = HI32; 1776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (upper_special) 1777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HI32 = LO32; 1778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0; i < 4; ++i) { 1780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t val = 0; 1781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int j = 0; j < 4; ++j) { 1782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue V; 1783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool process_upper, process_lower; 1784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman val <<= 8; 1785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman process_upper = (upper_special && (i & 1) == 0); 1786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman process_lower = (lower_special && (i & 1) == 1); 1787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (process_upper || process_lower) { 1789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((process_upper && upper == 0) 1790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (process_lower && lower == 0)) 1791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman val |= 0x80; 1792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if ((process_upper && upper == 0xffffffff) 1793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (process_lower && lower == 0xffffffff)) 1794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman val |= 0xc0; 1795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if ((process_upper && upper == 0x80000000) 1796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (process_lower && lower == 0x80000000)) 1797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman val |= (j == 0 ? 0xe0 : 0x80); 1798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else 1799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman val |= i * 4 + j + ((i & 1) * 16); 1800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes.push_back(DAG.getConstant(val, MVT::i32)); 1803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::SHUFB, dl, OpVT, HI32, LO32, 1806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ShufBytes[0], ShufBytes.size())); 1808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on 1812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// which the Cell can operate. The code inspects V3 to ascertain whether the 1813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// permutation vector, V3, is monotonically increasing with one "exception" 1814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// element, e.g., (0, 1, _, 3). If this is the case, then generate a 1815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool. 1816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// In either case, the net result is going to eventually invoke SHUFB to 1817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// permute/shuffle the bytes from V1 and V2. 1818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \note 1819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate 1820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// control word for byte/halfword/word insertion. This takes care of a single 1821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// element move from V2 into V1. 1822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \note 1823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions. 1824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { 1825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op); 1826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue V1 = Op.getOperand(0); 1827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue V2 = Op.getOperand(1); 1828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (V2.getOpcode() == ISD::UNDEF) V2 = V1; 1831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have a single element being moved from V1 to V2, this can be handled 1833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // using the C*[DX] compute mask instructions, but the vector elements have 183419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // to be monotonically increasing with one exception element, and the source 183519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // slot of the element to move must be the same as the destination. 1836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VecVT = V1.getValueType(); 1837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = VecVT.getVectorElementType(); 1838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EltsFromV2 = 0; 183919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned V2EltOffset = 0; 1840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned V2EltIdx0 = 0; 1841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CurrElt = 0; 1842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned MaxElts = VecVT.getVectorNumElements(); 1843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned PrevElt = 0; 1844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool monotonic = true; 1845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool rotate = true; 184619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int rotamt=0; 1847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT maskVT; // which of the c?d instructions to use 1848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (EltVT == MVT::i8) { 1850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman V2EltIdx0 = 16; 185119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman maskVT = MVT::v16i8; 1852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (EltVT == MVT::i16) { 1853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman V2EltIdx0 = 8; 1854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maskVT = MVT::v8i16; 1855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (EltVT == MVT::i32 || EltVT == MVT::f32) { 1856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman V2EltIdx0 = 4; 1857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maskVT = MVT::v4i32; 1858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (EltVT == MVT::i64 || EltVT == MVT::f64) { 1859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman V2EltIdx0 = 2; 1860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maskVT = MVT::v2i64; 1861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else 1862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Unhandled vector type in LowerVECTOR_SHUFFLE"); 1863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != MaxElts; ++i) { 1865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SVN->getMaskElt(i) < 0) 1866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 186719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SrcElt = SVN->getMaskElt(i); 1869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (monotonic) { 1871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SrcElt >= V2EltIdx0) { 187219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // TODO: optimize for the monotonic case when several consecutive 187319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // elements are taken form V2. Do we ever get such a case? 187419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (EltsFromV2 == 0 && CurrElt == (SrcElt - V2EltIdx0)) 187519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman V2EltOffset = (SrcElt - V2EltIdx0) * (EltVT.getSizeInBits()/8); 187619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 187719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman monotonic = false; 187819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++EltsFromV2; 1879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (CurrElt != SrcElt) { 1880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman monotonic = false; 1881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++CurrElt; 1884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (rotate) { 1887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (PrevElt > 0 && SrcElt < MaxElts) { 1888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((PrevElt == SrcElt - 1) 1889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || (PrevElt == MaxElts - 1 && SrcElt == 0)) { 1890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PrevElt = SrcElt; 1891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rotate = false; 1893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 189419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (i == 0 || (PrevElt==0 && SrcElt==1)) { 189519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // First time or after a "wrap around" 189619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotamt = SrcElt-i; 1897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PrevElt = SrcElt; 1898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This isn't a rotation, takes elements from vector 2 1900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rotate = false; 1901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (EltsFromV2 == 1 && monotonic) { 1906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Compute mask and shuffle 1907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 1908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // As SHUFFLE_MASK becomes a c?d instruction, feed it an address 1910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // R1 ($sp) is used here only as it is guaranteed to have last bits zero 1911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 1912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getRegister(SPU::R1, PtrVT), 191319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(V2EltOffset, MVT::i32)); 191419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ShufMaskOp = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, 1915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maskVT, Pointer); 1916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use shuffle mask in SHUFB synthetic instruction: 1918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1, 1919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufMaskOp); 1920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (rotate) { 192119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rotamt < 0) 192219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotamt +=MaxElts; 192319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rotamt *= EltVT.getSizeInBits()/8; 1924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(), 1925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman V1, DAG.getConstant(rotamt, MVT::i16)); 1926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert the SHUFFLE_VECTOR mask's input element units to the 1928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // actual bytes. 1929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned BytesPerElement = EltVT.getSizeInBits()/8; 1930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16> ResultMask; 1932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = MaxElts; i != e; ++i) { 1933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SrcElt = SVN->getMaskElt(i) < 0 ? 0 : SVN->getMaskElt(i); 1934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned j = 0; j < BytesPerElement; ++j) 1936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,MVT::i8)); 1937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8, 1939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ResultMask[0], ResultMask.size()); 1940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask); 1941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) { 1945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = Op.getOperand(0); // Op0 = the scalar 1946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getNode()->getOpcode() == ISD::Constant) { 1949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For a constant, build the appropriate constant vector, which will 1950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // eventually simplify to a vector register load. 1951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode()); 1953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16> ConstVecValues; 1954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT; 1955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t n_copies; 1956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create a constant vector: 1958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op.getValueType().getSimpleVT().SimpleTy) { 1959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected constant value type in " 1960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "LowerSCALAR_TO_VECTOR"); 1961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v16i8: n_copies = 16; VT = MVT::i8; break; 1962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v8i16: n_copies = 8; VT = MVT::i16; break; 1963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4i32: n_copies = 4; VT = MVT::i32; break; 1964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v4f32: n_copies = 4; VT = MVT::f32; break; 1965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2i64: n_copies = 2; VT = MVT::i64; break; 1966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::v2f64: n_copies = 2; VT = MVT::f64; break; 1967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT); 1970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (size_t j = 0; j < n_copies; ++j) 1971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstVecValues.push_back(CValue); 1972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(), 1974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ConstVecValues[0], ConstVecValues.size()); 1975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, copy the value from one register to another: 1977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op0.getValueType().getSimpleVT().SimpleTy) { 1978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type in LowerSCALAR_TO_VECTOR"); 1979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: 1980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: 1981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 1982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 1983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: 1984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: 1985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::PREFSLOT2VEC, dl, Op.getValueType(), Op0, Op0); 1986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 1990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) { 1993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 1994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N = Op.getOperand(0); 1995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Elt = Op.getOperand(1); 1996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue retval; 1998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) { 2000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Constant argument: 2001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int EltNo = (int) C->getZExtValue(); 2002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sanity checks: 2004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i8 && EltNo >= 16) 2005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15"); 2006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i16 && EltNo >= 8) 2007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7"); 2008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32 && EltNo >= 4) 2009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4"); 2010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64 && EltNo >= 2) 2011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2"); 2012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) { 2014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // i32 and i64: Element 0 is the preferred slot 2015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, N); 2016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Need to generate shuffle mask and extract: 2019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int prefslot_begin = -1, prefslot_end = -1; 2020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int elt_byte = EltNo * VT.getSizeInBits() / 8; 2021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.getSimpleVT().SimpleTy) { 2023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(false && "Invalid value type!"); 2025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: { 2026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman prefslot_begin = prefslot_end = 3; 2027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: { 2030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman prefslot_begin = 2; prefslot_end = 3; 2031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 2034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: { 2035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman prefslot_begin = 0; prefslot_end = 3; 2036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 2039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: { 2040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman prefslot_begin = 0; prefslot_end = 7; 2041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(prefslot_begin != -1 && prefslot_end != -1 && 2046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized"); 2047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int ShufBytes[16] = { 2049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 2050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 2051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0; i < 16; ++i) { 2052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // zero fill uppper part of preferred slot, don't care about the 2053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // other slots: 2054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int mask_val; 2055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i <= prefslot_end) { 2056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mask_val = 2057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((i < prefslot_begin) 2058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? 0x80 2059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : elt_byte + (i - prefslot_begin)); 2060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes[i] = mask_val; 2062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else 2063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)]; 2064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShufMask[4]; 2067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) { 2068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bidx = i * 4; 2069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int bits = ((ShufBytes[bidx] << 24) | 2070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (ShufBytes[bidx+1] << 16) | 2071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (ShufBytes[bidx+2] << 8) | 2072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufBytes[bidx+3]); 2073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufMask[i] = DAG.getConstant(bits, MVT::i32); 2074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShufMaskVec = 2077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ShufMask[0], sizeof(ShufMask)/sizeof(ShufMask[0])); 2079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, 2081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(SPUISD::SHUFB, dl, N.getValueType(), 2082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N, N, ShufMaskVec)); 2083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Variable index: Rotate the requested element into slot 0, then replicate 2085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // slot 0 across the vector 2086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VecVT = N.getValueType(); 2087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!VecVT.isSimple() || !VecVT.isVector()) { 2088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit" 2089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "vector type!"); 2090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make life easier by making sure the index is zero-extended to i32 2093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Elt.getValueType() != MVT::i32) 2094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Elt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Elt); 2095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scale the index to a bit/byte shift quantity 2097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt scaleFactor = 2098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false); 2099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned scaleShift = scaleFactor.logBase2(); 2100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue vecShift; 2101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (scaleShift > 0) { 2103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scale the shift factor: 2104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Elt = DAG.getNode(ISD::SHL, dl, MVT::i32, Elt, 2105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(scaleShift, MVT::i32)); 2106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 210819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman vecShift = DAG.getNode(SPUISD::SHL_BYTES, dl, VecVT, N, Elt); 2109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Replicate the bytes starting at byte 0 across the entire vector (for 2111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // consistency with the notion of a unified register set) 2112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue replicate; 2113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.getSimpleVT().SimpleTy) { 2115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector" 2117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "type"); 2118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 2119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: { 2120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue factor = DAG.getConstant(0x00000000, MVT::i32); 2121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman factor, factor, factor, factor); 2123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: { 2126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue factor = DAG.getConstant(0x00010001, MVT::i32); 2127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman factor, factor, factor, factor); 2129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 2132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: { 2133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue factor = DAG.getConstant(0x00010203, MVT::i32); 2134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman factor, factor, factor, factor); 2136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 2139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: { 2140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32); 2141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32); 2142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loFactor, hiFactor, loFactor, hiFactor); 2144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, 2149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(SPUISD::SHUFB, dl, VecVT, 2150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman vecShift, vecShift, replicate)); 2151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return retval; 2154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) { 2157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue VecOp = Op.getOperand(0); 2158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ValOp = Op.getOperand(1); 2159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue IdxOp = Op.getOperand(2); 2160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 216219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT eltVT = ValOp.getValueType(); 2163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use 0 when the lane to insert to is 'undef' 216519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t Offset=0; 2166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (IdxOp.getOpcode() != ISD::UNDEF) { 2167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp); 2168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!"); 216919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = (CN->getSExtValue()) * eltVT.getSizeInBits()/8; 2170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 2173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use $sp ($1) because it's always 16-byte aligned and it's available: 2174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, 2175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getRegister(SPU::R1, PtrVT), 217619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(Offset, PtrVT)); 2177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // widen the mask when dealing with half vectors 217819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT maskVT = EVT::getVectorVT(*(DAG.getContext()), VT.getVectorElementType(), 2179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 128/ VT.getVectorElementType().getSizeInBits()); 2180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, maskVT, Pointer); 2181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue result = 2183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(SPUISD::SHUFB, dl, VT, 2184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, ValOp), 2185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VecOp, 218619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, ShufMask)); 2187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return result; 2189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc, 2192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetLowering &TLI) 2193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N0 = Op.getOperand(0); // Everything has at least one operand 2195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 219619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ShiftVT = TLI.getShiftAmountTy(N0.getValueType()); 2197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Op.getValueType() == MVT::i8); 2199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Opc) { 2200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Unhandled i8 math operator"); 2202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 2203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADD: { 2205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 8-bit addition: Promote the arguments up to 16-bits and truncate 2206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the result: 2207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1 = Op.getOperand(1); 2208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0); 2209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1); 2210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, 2211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Opc, dl, MVT::i16, N0, N1)); 2212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUB: { 2216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 8-bit subtraction: Promote the arguments up to 16-bits and truncate 2217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the result: 2218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1 = Op.getOperand(1); 2219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0); 2220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1); 2221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, 2222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Opc, dl, MVT::i16, N0, N1)); 2223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTR: 2225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTL: { 2226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1 = Op.getOperand(1); 2227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT N1VT = N1.getValueType(); 2228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0); 2230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!N1VT.bitsEq(ShiftVT)) { 2231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned N1Opc = N1.getValueType().bitsLT(ShiftVT) 2232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? ISD::ZERO_EXTEND 2233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : ISD::TRUNCATE; 2234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1); 2235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Replicate lower 8-bits into upper 8: 2238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandArg = 2239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::OR, dl, MVT::i16, N0, 2240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SHL, dl, MVT::i16, 2241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0, DAG.getConstant(8, MVT::i32))); 2242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Truncate back down to i8 2244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, 2245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Opc, dl, MVT::i16, ExpandArg, N1)); 2246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 2248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: { 2249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1 = Op.getOperand(1); 2250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT N1VT = N1.getValueType(); 2251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0); 2253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!N1VT.bitsEq(ShiftVT)) { 2254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned N1Opc = ISD::ZERO_EXTEND; 2255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N1.getValueType().bitsGT(ShiftVT)) 2257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1Opc = ISD::TRUNCATE; 2258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1); 2260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, 2263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Opc, dl, MVT::i16, N0, N1)); 2264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: { 2266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1 = Op.getOperand(1); 2267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT N1VT = N1.getValueType(); 2268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0); 2270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!N1VT.bitsEq(ShiftVT)) { 2271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned N1Opc = ISD::SIGN_EXTEND; 2272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N1VT.bitsGT(ShiftVT)) 2274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1Opc = ISD::TRUNCATE; 2275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1); 2276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, 2279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Opc, dl, MVT::i16, N0, N1)); 2280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MUL: { 2282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1 = Op.getOperand(1); 2283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0); 2285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1); 2286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, 2287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Opc, dl, MVT::i16, N0, N1)); 2288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 2293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Lower byte immediate operations for v16i8 vectors: 2296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue 2297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanLowerByteImmed(SDValue Op, SelectionDAG &DAG) { 2298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ConstVec; 2299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Arg; 2300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 2301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstVec = Op.getOperand(0); 2304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Arg = Op.getOperand(1); 2305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) { 230619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ConstVec.getNode()->getOpcode() == ISD::BITCAST) { 2307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstVec = ConstVec.getOperand(0); 2308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstVec = Op.getOperand(1); 2310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Arg = Op.getOperand(0); 231119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ConstVec.getNode()->getOpcode() == ISD::BITCAST) { 2312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstVec = ConstVec.getOperand(0); 2313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) { 2318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(ConstVec.getNode()); 2319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerByteImmed"); 2320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt APSplatBits, APSplatUndef; 2322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SplatBitSize; 2323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasAnyUndefs; 2324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned minSplatBits = VT.getVectorElementType().getSizeInBits(); 2325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize, 2327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HasAnyUndefs, minSplatBits) 2328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && minSplatBits <= SplatBitSize) { 2329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t SplatBits = APSplatBits.getZExtValue(); 2330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8); 2331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16> tcVec; 2333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman tcVec.assign(16, tc); 2334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(Op.getNode()->getOpcode(), dl, VT, Arg, 2335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &tcVec[0], tcVec.size())); 2336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // These operations (AND, OR, XOR) are legal, they just couldn't be custom 2340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lowered. Return the operation, rather than a null SDValue. 2341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op; 2342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Custom lowering for CTPOP (count population) 2345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Custom lowering code that counts the number ones in the input 2347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman operand. SPU has such an instruction, but it counts the number of 2348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ones per byte, which then have to be accumulated. 2349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman*/ 2350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) { 2351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 235219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT vecVT = EVT::getVectorVT(*DAG.getContext(), 2353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VT, (128 / VT.getSizeInBits())); 2354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.getSimpleVT().SimpleTy) { 2357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(false && "Invalid value type!"); 2359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: { 2360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N = Op.getOperand(0); 2361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Elt0 = DAG.getConstant(0, MVT::i32); 2362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N); 2364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote); 2365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i8, CNTB, Elt0); 2367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: { 2370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFunction &MF = DAG.getMachineFunction(); 2371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineRegisterInfo &RegInfo = MF.getRegInfo(); 2372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass); 2374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N = Op.getOperand(0); 2376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Elt0 = DAG.getConstant(0, MVT::i16); 2377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16); 2378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Shift1 = DAG.getConstant(8, MVT::i32); 2379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N); 2381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote); 2382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CNTB_result becomes the chain to which all of the virtual registers 2384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CNTB_reg, SUM1_reg become associated: 2385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB_result = 2386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, CNTB, Elt0); 2387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB_rescopy = 2389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result); 2390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i16); 2392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::AND, dl, MVT::i16, 2394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::ADD, dl, MVT::i16, 2395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, MVT::i16, 2396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Shift1), 2397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1), 2398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Mask0); 2399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: { 2402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFunction &MF = DAG.getMachineFunction(); 2403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineRegisterInfo &RegInfo = MF.getRegInfo(); 2404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass); 2406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass); 2407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N = Op.getOperand(0); 2409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Elt0 = DAG.getConstant(0, MVT::i32); 2410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Mask0 = DAG.getConstant(0xff, MVT::i32); 2411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Shift1 = DAG.getConstant(16, MVT::i32); 2412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Shift2 = DAG.getConstant(8, MVT::i32); 2413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N); 2415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote); 2416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CNTB_result becomes the chain to which all of the virtual registers 2418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CNTB_reg, SUM1_reg become associated: 2419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB_result = 2420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, CNTB, Elt0); 2421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CNTB_rescopy = 2423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result); 2424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Comp1 = 2426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, MVT::i32, 2427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32), 2428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift1); 2429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum1 = 2431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::ADD, dl, MVT::i32, Comp1, 2432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32)); 2433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum1_rescopy = 2435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyToReg(CNTB_result, dl, SUM1_reg, Sum1); 2436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Comp2 = 2438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, MVT::i32, 2439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32), 2440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Shift2); 2441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum2 = 2442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::ADD, dl, MVT::i32, Comp2, 2443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32)); 2444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::AND, dl, MVT::i32, Sum2, Mask0); 2446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 2449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 2453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32 2456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall. 2458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman All conversions to i64 are expanded to a libcall. 2459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 2460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, 2461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SPUTargetLowering &TLI) { 2462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = Op.getValueType(); 2463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = Op.getOperand(0); 2464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT Op0VT = Op0.getValueType(); 2465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((OpVT == MVT::i32 && Op0VT == MVT::f64) 2467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || OpVT == MVT::i64) { 2468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert f32 / f64 to i32 / i64 via libcall. 2469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = 2470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (Op.getOpcode() == ISD::FP_TO_SINT) 2471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? RTLIB::getFPTOSINT(Op0VT, OpVT) 2472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : RTLIB::getFPTOUINT(Op0VT, OpVT); 2473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!"); 2474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Dummy; 2475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI); 2476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op; 2479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32 2482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall. 2484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman All conversions from i64 are expanded to a libcall. 2485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 2486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG, 2487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SPUTargetLowering &TLI) { 2488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = Op.getValueType(); 2489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = Op.getOperand(0); 2490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT Op0VT = Op0.getValueType(); 2491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((OpVT == MVT::f64 && Op0VT == MVT::i32) 2493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || Op0VT == MVT::i64) { 2494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert i32, i64 to f64 via libcall: 2495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = 2496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (Op.getOpcode() == ISD::SINT_TO_FP) 2497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? RTLIB::getSINTTOFP(Op0VT, OpVT) 2498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : RTLIB::getUINTTOFP(Op0VT, OpVT); 2499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!"); 2500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Dummy; 2501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI); 2502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op; 2505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Lower ISD::SETCC 2508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman This handles MVT::f64 (double floating point) condition lowering 2510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 2511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG, 2512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetLowering &TLI) { 2513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2)); 2514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n"); 2516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhs = Op.getOperand(0); 2518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhs = Op.getOperand(1); 2519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT lhsVT = lhs.getValueType(); 2520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n"); 2521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType()); 2523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits()); 2524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT IntVT(MVT::i64); 2525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently 2527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // selected to a NOP: 252819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue i64lhs = DAG.getNode(ISD::BITCAST, dl, IntVT, lhs); 2529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsHi32 = 2530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, 2531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, IntVT, 2532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman i64lhs, DAG.getConstant(32, MVT::i32))); 2533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsHi32abs = 2534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::AND, dl, MVT::i32, 2535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32)); 2536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsLo32 = 2537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs); 2538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SETO and SETUO only use the lhs operand: 2540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CC->get() == ISD::SETO) { 2541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of 2542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SETUO 2543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits()); 2544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::XOR, dl, ccResultVT, 2545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getSetCC(dl, ccResultVT, 2546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhs, DAG.getConstantFP(0.0, lhsVT), 2547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETUO), 2548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(ccResultAllOnes, ccResultVT)); 2549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (CC->get() == ISD::SETUO) { 2550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Evaluates to true if Op0 is [SQ]NaN 2551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::AND, dl, ccResultVT, 2552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getSetCC(dl, ccResultVT, 2553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhsHi32abs, 2554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0x7ff00000, MVT::i32), 2555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETGE), 2556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getSetCC(dl, ccResultVT, 2557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhsLo32, 2558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0, MVT::i32), 2559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETGT)); 2560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 256219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue i64rhs = DAG.getNode(ISD::BITCAST, dl, IntVT, rhs); 2563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhsHi32 = 2564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, 2565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, IntVT, 2566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman i64rhs, DAG.getConstant(32, MVT::i32))); 2567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If a value is negative, subtract from the sign magnitude constant: 2569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT); 2570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert the sign-magnitude representation into 2's complement: 2572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT, 2573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhsHi32, DAG.getConstant(31, MVT::i32)); 2574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs); 2575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsSelect = 2576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SELECT, dl, IntVT, 2577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhsSelectMask, lhsSignMag2TC, i64lhs); 2578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT, 2580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rhsHi32, DAG.getConstant(31, MVT::i32)); 2581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs); 2582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhsSelect = 2583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SELECT, dl, IntVT, 2584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rhsSelectMask, rhsSignMag2TC, i64rhs); 2585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned compareOp; 2587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (CC->get()) { 2589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOEQ: 2590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUEQ: 2591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman compareOp = ISD::SETEQ; break; 2592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOGT: 2593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGT: 2594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman compareOp = ISD::SETGT; break; 2595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOGE: 2596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGE: 2597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman compareOp = ISD::SETGE; break; 2598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOLT: 2599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULT: 2600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman compareOp = ISD::SETLT; break; 2601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOLE: 2602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULE: 2603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman compareOp = ISD::SETLE; break; 2604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUNE: 2605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETONE: 2606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman compareOp = ISD::SETNE; break; 2607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("CellSPU ISel Select: unimplemented f64 condition"); 2609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue result = 2612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect, 2613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (ISD::CondCode) compareOp); 2614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((CC->get() & 0x8) == 0) { 2616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ordered comparison: 2617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT, 2618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhs, DAG.getConstantFP(0.0, MVT::f64), 2619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETO); 2620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT, 2621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman rhs, DAG.getConstantFP(0.0, MVT::f64), 2622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETO); 2623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN); 2624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result); 2626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return result; 2629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Lower ISD::SELECT_CC 2632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SELECT_CC can (generally) be implemented directly on the SPU using the 2634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SELB instruction. 2635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \note Need to revisit this in the future: if the code path through the true 2637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman and false value computations is longer than the latency of a branch (6 2638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cycles), then it would be more advantageous to branch and insert a new basic 2639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman block and branch on the condition. However, this code does not make that 2640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assumption, given the simplisitc uses so far. 2641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 2642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG, 2644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetLowering &TLI) { 2645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 2646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue lhs = Op.getOperand(0); 2647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue rhs = Op.getOperand(1); 2648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue trueval = Op.getOperand(2); 2649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue falseval = Op.getOperand(3); 2650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue condition = Op.getOperand(4); 2651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: SELB's arguments: $rA, $rB, $mask 2654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 2655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SELB selects bits from $rA where bits in $mask are 0, bits from $rB 2656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // where bits in $mask are 1. CCond will be inverted, having 1s where the 2657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // condition was true and 0s where the condition was false. Hence, the 2658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // arguments to SELB get reversed. 2659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's 2661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up 2662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // with another "cannot select select_cc" assert: 2663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue compare = DAG.getNode(ISD::SETCC, dl, 2665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getSetCCResultType(Op.getValueType()), 2666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lhs, rhs, condition); 2667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::SELB, dl, VT, falseval, trueval, compare); 2668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Custom lower ISD::TRUNCATE 2671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) 2672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Type to truncate to 2674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 2675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT simpleVT = VT.getSimpleVT(); 267619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VecVT = EVT::getVectorVT(*DAG.getContext(), 2677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VT, (128 / VT.getSizeInBits())); 2678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Type to truncate from 2681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = Op.getOperand(0); 2682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT Op0VT = Op0.getValueType(); 2683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 268419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Op0VT == MVT::i128 && simpleVT == MVT::i64) { 2685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create shuffle mask, least significant doubleword of quadword 2686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned maskHigh = 0x08090a0b; 2687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned maskLow = 0x0c0d0e0f; 2688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use a shuffle to perform the truncation 2689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(maskHigh, MVT::i32), 2691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(maskLow, MVT::i32), 2692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(maskHigh, MVT::i32), 2693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(maskLow, MVT::i32)); 2694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, dl, VecVT, 2696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0, Op0, shufMask); 2697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, truncShuffle); 2699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); // Leave the truncate unmolested 2702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64/i32 -> i128 sign extend. The basic 2706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * algorithm is to duplicate the sign bit using rotmai to generate at 2707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * least one byte full of sign bits. Then propagate the "sign-byte" into 2708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * the leftmost words and the i64/i32 into the rightmost words using shufb. 2709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 2710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The sext operand 2711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param DAG The current DAG 2712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDValue with the entire instruction sequence 2713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 2714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) 2715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 2717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Type to extend to 2719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT OpVT = Op.getValueType().getSimpleVT(); 2720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Type to extend from 2722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = Op.getOperand(0); 2723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT Op0VT = Op0.getValueType().getSimpleVT(); 2724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 272519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // extend i8 & i16 via i32 272619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Op0VT == MVT::i8 || Op0VT == MVT::i16) { 272719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i32, Op0); 272819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0VT = MVT::i32; 272919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 273019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The type to extend to needs to be a i128 and 2732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the type to extend from needs to be i64 or i32. 2733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((OpVT == MVT::i128 && (Op0VT == MVT::i64 || Op0VT == MVT::i32)) && 2734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "LowerSIGN_EXTEND: input and/or output operand have wrong size"); 273519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (void)OpVT; 2736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create shuffle mask 2738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned mask1 = 0x10101010; // byte 0 - 3 and 4 - 7 2739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned mask2 = Op0VT == MVT::i64 ? 0x00010203 : 0x10101010; // byte 8 - 11 2740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned mask3 = Op0VT == MVT::i64 ? 0x04050607 : 0x00010203; // byte 12 - 15 2741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(mask1, MVT::i32), 2743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(mask1, MVT::i32), 2744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(mask2, MVT::i32), 2745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(mask3, MVT::i32)); 2746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Word wise arithmetic right shift to generate at least one byte 2748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // that contains sign bits. 2749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT mvt = Op0VT == MVT::i64 ? MVT::v2i64 : MVT::v4i32; 2750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue sraVal = DAG.getNode(ISD::SRA, 2751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dl, 2752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mvt, 2753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(SPUISD::PREFSLOT2VEC, dl, mvt, Op0, Op0), 2754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(31, MVT::i32)); 2755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 275619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // reinterpret as a i128 (SHUFB requires it). This gets lowered away. 275719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue extended = SDValue(DAG.getMachineNode(TargetOpcode::COPY_TO_REGCLASS, 275819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dl, Op0VT, Op0, 275919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getTargetConstant( 276019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SPU::GPRCRegClass.getID(), 276119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::i32)), 0); 2762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Shuffle bytes - Copy the sign bits into the upper 64 bits 2763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and the input value into the lower 64 bits. 2764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue extShuffle = DAG.getNode(SPUISD::SHUFB, dl, mvt, 276519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman extended, sraVal, shufMask); 276619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, MVT::i128, extShuffle); 2767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Custom (target-specific) lowering entry point 2770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 2771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman This is where LLVM's DAG selection process calls to do target-specific 2772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman lowering of nodes. 2773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 2774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 2775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const 2776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = (unsigned) Op.getOpcode(); 2778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 2779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Opc) { 2781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: { 2782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 2783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "SPUTargetLowering::LowerOperation(): need to lower this!\n"; 2784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "Op.getOpcode() = " << Opc << "\n"; 2785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "*Op.getNode():\n"; 2786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getNode()->dump(); 2787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 2788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable(0); 2789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::LOAD: 2791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTLOAD: 2792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SEXTLOAD: 2793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ZEXTLOAD: 2794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl()); 2795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STORE: 2796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl()); 2797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ConstantPool: 2798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl()); 2799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::GlobalAddress: 2800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl()); 2801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::JumpTable: 2802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl()); 2803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ConstantFP: 2804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerConstantFP(Op, DAG); 2805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // i8, i64 math ops: 2807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADD: 2808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUB: 2809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTR: 2810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTL: 2811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 2812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 2813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: { 2814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i8) 2815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerI8Math(Op, DAG, Opc, *this); 2816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_SINT: 2820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_UINT: 2821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerFP_TO_INT(Op, DAG, *this); 2822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SINT_TO_FP: 2824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UINT_TO_FP: 2825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerINT_TO_FP(Op, DAG, *this); 2826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Vector-related lowering. 2828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_VECTOR: 2829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerBUILD_VECTOR(Op, DAG); 2830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SCALAR_TO_VECTOR: 2831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerSCALAR_TO_VECTOR(Op, DAG); 2832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VECTOR_SHUFFLE: 2833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerVECTOR_SHUFFLE(Op, DAG); 2834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_VECTOR_ELT: 2835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerEXTRACT_VECTOR_ELT(Op, DAG); 2836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INSERT_VECTOR_ELT: 2837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerINSERT_VECTOR_ELT(Op, DAG); 2838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately: 2840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AND: 2841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::OR: 2842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::XOR: 2843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerByteImmed(Op, DAG); 2844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Vector and i8 multiply: 2846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MUL: 2847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i8) 2848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerI8Math(Op, DAG, Opc, *this); 2849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTPOP: 2851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerCTPOP(Op, DAG); 2852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: 2854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerSELECT_CC(Op, DAG, *this); 2855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: 2857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerSETCC(Op, DAG, *this); 2858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TRUNCATE: 2860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerTRUNCATE(Op, DAG); 2861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND: 2863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LowerSIGN_EXTEND(Op, DAG); 2864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(); 2867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SPUTargetLowering::ReplaceNodeResults(SDNode *N, 2870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue>&Results, 2871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAG &DAG) const 2872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 0 2874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = (unsigned) N->getOpcode(); 2875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = N->getValueType(0); 2876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Opc) { 2878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: { 2879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n"; 2880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "Op.getOpcode() = " << Opc << "\n"; 2881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "*Op.getNode():\n"; 2882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->dump(); 2883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman abort(); 2884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*NOTREACHED*/ 2885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 2888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /* Otherwise, return unchanged */ 2890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 2893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Target Optimization Hooks 2894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 2895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 2897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const 2898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 0 2900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetMachine &TM = getTargetMachine(); 2901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 2902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SPUSubtarget *ST = SPUTM.getSubtargetImpl(); 2903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAG &DAG = DCI.DAG; 2904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0 = N->getOperand(0); // everything has at least one operand 2905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NodeVT = N->getValueType(0); // The node's value type 2906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT Op0VT = Op0.getValueType(); // The first operand's result 2907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Result; // Initially, empty result 2908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 2911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 2912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADD: { 2913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op1 = N->getOperand(1); 2914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getOpcode() == SPUISD::IndirectAddr 2916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || Op1.getOpcode() == SPUISD::IndirectAddr) { 2917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Normalize the operands to reduce repeated code 2918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue IndirectArg = Op0, AddArg = Op1; 2919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op1.getOpcode() == SPUISD::IndirectAddr) { 2921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndirectArg = Op1; 2922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddArg = Op0; 2923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isa<ConstantSDNode>(AddArg)) { 2926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg); 2927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue IndOp1 = IndirectArg.getOperand(1); 2928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CN0->isNullValue()) { 2930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (add (SPUindirect <arg>, <arg>), 0) -> 2931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect <arg>, <arg>) 2932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if !defined(NDEBUG) 2934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { 2935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\n" 2936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n" 2937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "With: (SPUindirect <arg>, <arg>)\n"; 2938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 2940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return IndirectArg; 2942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (isa<ConstantSDNode>(IndOp1)) { 2943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (add (SPUindirect <arg>, <const>), <const>) -> 2944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect <arg>, <const + const>) 2945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1); 2946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue(); 2947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT); 2948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if !defined(NDEBUG) 2950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { 2951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\n" 2952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue() 2953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "), " << CN0->getSExtValue() << ")\n" 2954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "With: (SPUindirect <arg>, " 2955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << combinedConst << ")\n"; 2956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 2958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT, 2960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndirectArg, combinedValue); 2961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND: 2967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ZERO_EXTEND: 2968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ANY_EXTEND: { 2969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) { 2970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (any_extend (SPUextract_elt0 <arg>)) -> 2971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUextract_elt0 <arg>) 2972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Types must match, however... 2973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if !defined(NDEBUG) 2974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { 2975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\nReplace: "; 2976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->dump(&DAG); 2977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\nWith: "; 2978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0.getNode()->dump(&DAG); 2979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\n"; 2980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 2982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op0; 2984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::IndirectAddr: { 2988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) { 2989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)); 2990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CN != 0 && CN->isNullValue()) { 2991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect (SPUaform <addr>, 0), 0) -> 2992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUaform <addr>, 0) 2993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Replace: "); 2995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(N->dump(&DAG)); 2996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "\nWith: "); 2997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(Op0.getNode()->dump(&DAG)); 2998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "\n"); 2999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op0; 3001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Op0.getOpcode() == ISD::ADD) { 3003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op1 = N->getOperand(1); 3004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) { 3005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect (add <arg>, <arg>), 0) -> 3006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUindirect <arg>, <arg>) 3007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CN1->isNullValue()) { 3008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if !defined(NDEBUG) 3010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { 3011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\n" 3012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n" 3013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "With: (SPUindirect <arg>, <arg>)\n"; 3014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 3016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT, 3018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0.getOperand(0), Op0.getOperand(1)); 3019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 302419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case SPUISD::SHL_BITS: 302519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case SPUISD::SHL_BYTES: 3026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::ROTBYTES_LEFT: { 3027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op1 = N->getOperand(1); 3028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Kill degenerate vector shifts: 3030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) { 3031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CN->isNullValue()) { 3032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = Op0; 3033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::PREFSLOT2VEC: { 3038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op0.getOpcode()) { 3039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 3040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ANY_EXTEND: 3042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ZERO_EXTEND: 3043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND: { 3044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) -> 3045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // <arg> 3046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // but only if the SPUprefslot2vec and <arg> types match. 3047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op00 = Op0.getOperand(0); 3048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) { 3049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op000 = Op00.getOperand(0); 3050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op000.getValueType() == NodeVT) { 3051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = Op000; 3052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::VEC2PREFSLOT: { 3057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (SPUprefslot2vec (SPUvec2prefslot <arg>)) -> 3058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // <arg> 3059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = Op0.getOperand(0); 3060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, return unchanged. 3068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 3069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Result.getNode()) { 3070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "\nReplace.SPU: "); 3071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(N->dump(&DAG)); 3072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "\nWith: "); 3073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(Result.getNode()->dump(&DAG)); 3074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "\n"); 3075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 3077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 3079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 3082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Inline Assembly Support 3083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 3084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getConstraintType - Given a constraint letter, return the type of 3086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constraint it is for this target. 3087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::ConstraintType 3088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const { 3089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstraintLetter.size() == 1) { 3090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (ConstraintLetter[0]) { 3091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 3092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'b': 3093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'r': 3094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'f': 3095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'v': 3096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'y': 3097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return C_RegisterClass; 3098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TargetLowering::getConstraintType(ConstraintLetter); 3101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 310319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Examine constraint type and operand type and determine a weight value. 310419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// This object must already have been set up with the operand type 310519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// and the current alternative constraint selected. 310619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanTargetLowering::ConstraintWeight 310719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSPUTargetLowering::getSingleConstraintMatchWeight( 310819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AsmOperandInfo &info, const char *constraint) const { 310919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ConstraintWeight weight = CW_Invalid; 311019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value *CallOperandVal = info.CallOperandVal; 311119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If we don't have a value, we can't do a match, 311219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // but allow it at the lowest weight. 311319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CallOperandVal == NULL) 311419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CW_Default; 311519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Look at the constraint type. 311619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (*constraint) { 311719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 311819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); 311919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 312019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //FIXME: Seems like the supported constraint letters were just copied 312119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // from PPC, as the following doesn't correspond to the GCC docs. 312219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // I'm leaving it so until someone adds the corresponding lowering support. 312319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 'b': 312419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 'r': 312519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 'f': 312619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 'd': 312719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 'v': 312819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 'y': 312919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman weight = CW_Register; 313019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 313119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 313219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return weight; 313319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 313419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstd::pair<unsigned, const TargetRegisterClass*> 3136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, 3137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT) const 3138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 3139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Constraint.size() == 1) { 3140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // GCC RS6000 Constraint Letters 3141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Constraint[0]) { 3142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'b': // R1-R31 3143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'r': // R0-R31 3144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i64) 3145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return std::make_pair(0U, SPU::R64CRegisterClass); 3146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return std::make_pair(0U, SPU::R32CRegisterClass); 3147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'f': 3148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::f32) 3149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return std::make_pair(0U, SPU::R32FPRegisterClass); 3150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::f64) 3151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return std::make_pair(0U, SPU::R64FPRegisterClass); 3152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 'v': 3154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return std::make_pair(0U, SPU::GPRCRegisterClass); 3155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 3159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Compute used/known bits for a SPU operand 3162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid 3163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, 3164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const APInt &Mask, 3165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt &KnownZero, 3166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt &KnownOne, 3167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SelectionDAG &DAG, 3168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Depth ) const { 3169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 0 3170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const uint64_t uint64_sizebits = sizeof(uint64_t) * CHAR_BIT; 3171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op.getOpcode()) { 3173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 3174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); 3175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case CALL: 3177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SHUFB: 3178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SHUFFLE_MASK: 3179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case CNTB: 3180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::PREFSLOT2VEC: 3181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::LDRESULT: 3182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::VEC2PREFSLOT: 3183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::SHLQUAD_L_BITS: 3184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::SHLQUAD_L_BYTES: 3185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::VEC_ROTL: 3186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::VEC_ROTR: 3187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::ROTBYTES_LEFT: 3188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::SELECT_MASK: 3189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPUISD::SELB: 3190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 3192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 3195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op, 3196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Depth) const { 3197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op.getOpcode()) { 3198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 3199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 1; 3200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: { 3202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 3203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) { 3205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VT = MVT::i32; 3206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return VT.getSizeInBits(); 3208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// LowerAsmOperandForConstraint 3213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid 3214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op, 321519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::string &Constraint, 3216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<SDValue> &Ops, 3217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAG &DAG) const { 3218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Default, for the time being, to the base class handler 321919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); 3220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// isLegalAddressImmediate - Return true if the integer value can be used 3223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// as the offset of the target addressing mode. 3224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool SPUTargetLowering::isLegalAddressImmediate(int64_t V, 322519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty) const { 3226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SPU's addresses are 256K: 3227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (V > -(1 << 18) && V < (1 << 18) - 1); 3228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const { 3231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 3232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 3235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { 3236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The SPU target isn't yet aware of offsets. 3237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 3238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 323919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 324019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// can we compare to Imm without writing it into a register? 324119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool SPUTargetLowering::isLegalICmpImmediate(int64_t Imm) const { 324219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //ceqi, cgti, etc. all take s10 operand 324319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return isInt<10>(Imm); 324419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 324519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 324619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool 324719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSPUTargetLowering::isLegalAddressingMode(const AddrMode &AM, 324819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type * ) const{ 324919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 325019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // A-form: 18bit absolute address. 325119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AM.BaseGV && !AM.HasBaseReg && AM.Scale == 0 && AM.BaseOffs == 0) 325219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 325319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 325419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // D-form: reg + 14bit offset 325519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AM.BaseGV ==0 && AM.HasBaseReg && AM.Scale == 0 && isInt<14>(AM.BaseOffs)) 325619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 325719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 325819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // X-form: reg+reg 325919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AM.BaseGV == 0 && AM.HasBaseReg && AM.Scale == 1 && AM.BaseOffs ==0) 326019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 326119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 326219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 326319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 3264